Merge "Adds AndroidTest.xml for AIDL sensors VTS test"
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/audio/OWNERS b/audio/OWNERS
new file mode 100644
index 0000000..ede448c
--- /dev/null
+++ b/audio/OWNERS
@@ -0,0 +1 @@
+per-file README.md = 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 7db50d5..ba22d7b 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -75,10 +75,14 @@
         "android/hardware/audio/core/IModule.aidl",
         "android/hardware/audio/core/IStreamIn.aidl",
         "android/hardware/audio/core/IStreamOut.aidl",
+        "android/hardware/audio/core/MmapBufferDescriptor.aidl",
         "android/hardware/audio/core/ModuleDebug.aidl",
+        "android/hardware/audio/core/StreamDescriptor.aidl",
     ],
     imports: [
         "android.hardware.audio.common-V1",
+        "android.hardware.common-V2",
+        "android.hardware.common.fmq-V1",
         "android.media.audio.common.types-V1",
     ],
     stability: "vintf",
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
index 1cef4cd..078b5ea 100644
--- 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
@@ -37,4 +37,6 @@
   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/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
index f8bc2c7..a8bbb15 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
@@ -43,10 +43,33 @@
   android.media.audio.common.AudioPort[] getAudioPorts();
   android.hardware.audio.core.AudioRoute[] getAudioRoutes();
   android.hardware.audio.core.AudioRoute[] getAudioRoutesForAudioPort(int portId);
-  android.hardware.audio.core.IStreamIn openInputStream(int portConfigId, in android.hardware.audio.common.SinkMetadata sinkMetadata);
-  android.hardware.audio.core.IStreamOut openOutputStream(int portConfigId, in android.hardware.audio.common.SourceMetadata sourceMetadata, in @nullable android.media.audio.common.AudioOffloadInfo offloadInfo);
+  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.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);
+  @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;
+  }
+  @VintfStability
+  parcelable OpenOutputStreamReturn {
+    android.hardware.audio.core.IStreamOut stream;
+    android.hardware.audio.core.StreamDescriptor desc;
+  }
 }
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/StreamDescriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl
new file mode 100644
index 0000000..472a8a2
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible 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;
+  long bufferSizeFrames;
+  android.hardware.audio.core.StreamDescriptor.AudioBuffer audio;
+  const int COMMAND_EXIT = 0;
+  const int COMMAND_BURST = 1;
+  const int STATUS_OK = 0;
+  const int STATUS_ILLEGAL_ARGUMENT = 1;
+  const int STATUS_ILLEGAL_STATE = 2;
+  @FixedSize @VintfStability
+  parcelable Position {
+    long frames;
+    long timeNs;
+  }
+  @FixedSize @VintfStability
+  parcelable Command {
+    int code;
+    int fmqByteCount;
+  }
+  @FixedSize @VintfStability
+  parcelable Reply {
+    int status;
+    int fmqByteCount;
+    android.hardware.audio.core.StreamDescriptor.Position observable;
+    android.hardware.audio.core.StreamDescriptor.Position hardware;
+    int latencyMs;
+  }
+  @VintfStability
+  union AudioBuffer {
+    android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.UnsynchronizedWrite> fmq;
+    android.hardware.audio.core.MmapBufferDescriptor mmap;
+  }
+}
diff --git a/audio/aidl/android/hardware/audio/core/AudioPatch.aidl b/audio/aidl/android/hardware/audio/core/AudioPatch.aidl
index 48ca214..005d4c0 100644
--- a/audio/aidl/android/hardware/audio/core/AudioPatch.aidl
+++ b/audio/aidl/android/hardware/audio/core/AudioPatch.aidl
@@ -37,4 +37,18 @@
      * 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/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index 802cb2f..363eb68 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -23,6 +23,7 @@
 import android.hardware.audio.core.IStreamIn;
 import android.hardware.audio.core.IStreamOut;
 import android.hardware.audio.core.ModuleDebug;
+import android.hardware.audio.core.StreamDescriptor;
 import android.media.audio.common.AudioOffloadInfo;
 import android.media.audio.common.AudioPort;
 import android.media.audio.common.AudioPortConfig;
@@ -241,22 +242,49 @@
      * '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.
      *
-     * @return An opened input stream.
-     * @param portConfigId The ID of the audio mix port config.
-     * @param sinkMetadata Description of the audio that will be recorded.
+     * 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 is not the recommended sequence of
+     * calls, because setting up of a patch might fail due to an insufficient
+     * stream buffer size.
+     *
+     * @return An opened input stream and the associated descriptor.
+     * @param args Input 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.
      */
-    IStreamIn openInputStream(int portConfigId, in SinkMetadata sinkMetadata);
+    @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.
@@ -269,21 +297,33 @@
      * the framework must provide additional information about the encoded
      * audio stream in 'offloadInfo' 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.
      *
-     * @return An opened output stream.
-     * @param portConfigId The ID of the audio mix port config.
-     * @param sourceMetadata Description of the audio that will be played.
-     * @param offloadInfo Additional information for offloaded playback.
+     * 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 is not the recommended sequence of
+     * calls, because setting up of a patch might fail due to an insufficient
+     * stream buffer size.
+     *
+     * @return An opened output stream and the associated descriptor.
+     * @param args Input 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.
      * @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
@@ -291,8 +331,23 @@
      *                          - If another opened stream already exists for the 'PRIMARY'
      *                            output port.
      */
-    IStreamOut openOutputStream(int portConfigId, in SourceMetadata sourceMetadata,
-            in @nullable AudioOffloadInfo offloadInfo);
+    @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;
+    }
+    @VintfStability
+    parcelable OpenOutputStreamReturn {
+        IStreamOut stream;
+        StreamDescriptor desc;
+    }
+    OpenOutputStreamReturn openOutputStream(in OpenOutputStreamArguments args);
 
     /**
      * Set an audio patch.
@@ -300,19 +355,27 @@
      * 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. It is recommended that
-     * updating of an existing audio patch should be performed by the HAL module
-     * in a way that does not interrupt active audio streams involving audio
-     * port configurations of the patch. If the HAL module is unable to avoid
-     * interruption when updating a certain patch, it is permitted to allocate a
-     * new patch ID for the result. The returned audio patch contains all the
-     * information about the new or updated audio patch.
+     * 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.
-     * An audio patch may be created before or after an audio steam is created
-     * for this configuration.
+     *
+     * 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.
@@ -324,6 +387,9 @@
      * @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
diff --git a/audio/aidl/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
index b770449..7205bb8 100644
--- a/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
+++ b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
@@ -28,7 +28,9 @@
      *
      * Releases any resources allocated for this stream on the HAL module side.
      * The stream can not be operated after it has been closed. Methods of this
-     * interface throw EX_ILLEGAL_STATE in for a closed stream.
+     * interface throw EX_ILLEGAL_STATE for a closed stream.
+     *
+     * The associated stream descriptor can be released once this method returns.
      *
      * @throws EX_ILLEGAL_STATE If the stream has already been closed.
      */
diff --git a/audio/aidl/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
index 60212fc..0a5aacd 100644
--- a/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
+++ b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
@@ -28,7 +28,9 @@
      *
      * Releases any resources allocated for this stream on the HAL module side.
      * The stream can not be operated after it has been closed. Methods of this
-     * interface throw EX_ILLEGAL_STATE in for a closed stream.
+     * interface throw EX_ILLEGAL_STATE for a closed stream.
+     *
+     * The associated stream descriptor can be released once this method returns.
      *
      * @throws EX_ILLEGAL_STATE If the stream has already been closed.
      */
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/StreamDescriptor.aidl b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
new file mode 100644
index 0000000..f2338e0
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.hardware.common.fmq.UnsynchronizedWrite;
+
+/**
+ * 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.
+ */
+@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 {
+        /** Frame count. */
+        long frames;
+        /** Timestamp in nanoseconds. */
+        long timeNs;
+    }
+
+    /**
+     * The exit command is used to unblock the HAL thread and ask it to exit.
+     * This is the last command that the client sends via the StreamDescriptor.
+     * The HAL module must reply to this command in order to unblock the client,
+     * and cease waiting on the command queue.
+     */
+    const int COMMAND_EXIT = 0;
+    /**
+     * The command used for audio I/O, see 'AudioBuffer'. For 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.
+     */
+    const int COMMAND_BURST = 1;
+
+    /**
+     * 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.
+     */
+    @VintfStability
+    @FixedSize
+    parcelable Command {
+        /**
+         * One of COMMAND_* codes.
+         */
+        int code;
+        /**
+         * For output streams: the amount of bytes provided by the client 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.
+         */
+        int fmqByteCount;
+    }
+    MQDescriptor<Command, SynchronizedReadWrite> command;
+
+    /**
+     * No error, the command completed successfully.
+     */
+    const int STATUS_OK = 0;
+    /**
+     * Invalid data provided in the command, e.g. unknown command code or
+     * negative 'fmqByteCount' value.
+     */
+    const int STATUS_ILLEGAL_ARGUMENT = 1;
+    /**
+     * The HAL module is not in the state when it can complete the command.
+     */
+    const int STATUS_ILLEGAL_STATE = 2;
+
+    /**
+     * 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 STATUS_* statuses.
+         */
+        int status;
+        /**
+         * For output streams: the amount of bytes actually consumed by the HAL
+         *   module from the 'audio.fmq' queue.
+         * For input streams: the amount of bytes actually provided by the HAL
+         *   in the 'audio.fmq' queue.
+         */
+        int fmqByteCount;
+        /**
+         * 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).
+         */
+        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.
+         */
+        int latencyMs;
+    }
+    MQDescriptor<Reply, SynchronizedReadWrite> reply;
+
+    /**
+     * 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 all modes except MMap No IRQ. Access
+         * to this queue is synchronized via the 'command' and 'reply' queues
+         * as described below.
+         *
+         * For output streams the following sequence of operations is used:
+         *  1. The client puts 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.
+         *  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.
+         *
+         * 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 puts audio data into the 'audio.fmq' 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.
+         */
+        MQDescriptor<byte, UnsynchronizedWrite> 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 'BURST' command for obtaining current
+         * positions from the HAL module.
+         */
+        MmapBufferDescriptor mmap;
+    }
+    AudioBuffer audio;
+}
diff --git a/audio/aidl/common/Android.bp b/audio/aidl/common/Android.bp
new file mode 100644
index 0000000..37da9d6
--- /dev/null
+++ b/audio/aidl/common/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_library_headers {
+    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",
+    ],
+}
+
+cc_test {
+    name: "libaudioaidlcommon_test",
+    host_supported: true,
+    vendor_available: true,
+    header_libs: [
+        "libaudioaidlcommon",
+    ],
+    shared_libs: [
+        "liblog",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+    ],
+    srcs: [
+        "tests/streamworker_tests.cpp",
+    ],
+    test_suites: [
+        "general-tests",
+    ],
+}
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/StreamWorker.h b/audio/aidl/common/include/StreamWorker.h
new file mode 100644
index 0000000..7764904
--- /dev/null
+++ b/audio/aidl/common/include/StreamWorker.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.
+ */
+
+#pragma once
+
+#include <pthread.h>
+#include <sched.h>
+#include <sys/resource.h>
+
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+
+#include <android-base/thread_annotations.h>
+#include <system/thread_defs.h>
+
+template <typename Impl>
+class StreamWorker {
+    enum class WorkerState { STOPPED, RUNNING, PAUSE_REQUESTED, PAUSED, RESUME_REQUESTED };
+
+  public:
+    StreamWorker() = default;
+    ~StreamWorker() { stop(); }
+    // 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 `workerInit`.
+    bool start(const std::string& name = "", int priority = ANDROID_PRIORITY_DEFAULT) {
+        mThreadName = name;
+        mThreadPriority = priority;
+        mWorker = std::thread(&StreamWorker::workerThread, this);
+        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::RUNNING || !mError.empty();
+        });
+        mWorkerStateChangeRequest = false;
+        return mWorkerState == WorkerState::RUNNING;
+    }
+    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() {
+        {
+            std::lock_guard<std::mutex> lock(mWorkerLock);
+            if (mError.empty()) {
+                if (mWorkerState == WorkerState::STOPPED) return;
+                mWorkerState = WorkerState::STOPPED;
+                mWorkerStateChangeRequest = true;
+            }
+        }
+        if (mWorker.joinable()) {
+            mWorker.join();
+        }
+    }
+    bool 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;
+    }
+    // Only used by unit tests.
+    void testLockUnlockMutex(bool lock) NO_THREAD_SAFETY_ANALYSIS {
+        lock ? mWorkerLock.lock() : mWorkerLock.unlock();
+    }
+    std::thread::native_handle_type testGetThreadNativeHandle() { return mWorker.native_handle(); }
+
+    // Methods that need to be provided by subclasses:
+    //
+    // 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.
+    // std::string workerInit();
+    //
+    // Called for each thread loop unless the thread is in 'paused' state.
+    // Must return 'true' to continue running, otherwise the thread loop
+    // exits and the worker switches into the 'error' state with a generic
+    // error message. It is recommended that the subclass reports any
+    // problems via logging facilities.
+    // bool workerCycle();
+
+  private:
+    void switchWorkerStateSync(WorkerState oldState, WorkerState newState,
+                               WorkerState* finalState = nullptr) {
+        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 workerThread() {
+        std::string error = static_cast<Impl*>(this)->workerInit();
+        if (error.empty() && !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));
+            }
+        }
+        {
+            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 (state != WorkerState::PAUSED ? static_cast<Impl*>(this)->workerCycle()
+                                             : (sched_yield(), true)) {
+                {
+                    // 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;
+                mError = "workerCycle failed";
+            }
+            if (needToNotify) {
+                {
+                    std::lock_guard<std::mutex> lock(mWorkerLock);
+                    mWorkerStateChangeRequest = false;
+                }
+                mWorkerCv.notify_one();
+            }
+        }
+    }
+
+    std::string mThreadName;
+    int mThreadPriority = ANDROID_PRIORITY_DEFAULT;
+    std::thread mWorker;
+    std::mutex mWorkerLock;
+    std::condition_variable mWorkerCv;
+    WorkerState mWorkerState GUARDED_BY(mWorkerLock) = WorkerState::STOPPED;
+    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;
+};
diff --git a/audio/aidl/common/tests/streamworker_tests.cpp b/audio/aidl/common/tests/streamworker_tests.cpp
new file mode 100644
index 0000000..9fb1a8e
--- /dev/null
+++ b/audio/aidl/common/tests/streamworker_tests.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <unistd.h>
+
+#include <atomic>
+
+#include <StreamWorker.h>
+
+#include <gtest/gtest.h>
+#define LOG_TAG "StreamWorker_Test"
+#include <log/log.h>
+
+struct TestStream {
+    std::atomic<bool> error = false;
+};
+
+class TestWorker : public StreamWorker<TestWorker> {
+  public:
+    // Use nullptr to test error reporting from the worker thread.
+    explicit TestWorker(TestStream* 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;
+    }
+
+    std::string workerInit() { return mStream != nullptr ? "" : "Expected error"; }
+    bool workerCycle() {
+        mPriority = getpriority(PRIO_PROCESS, 0);
+        do {
+            mWorkerCycles++;
+        } while (mWorkerCycles == 0);
+        return !mStream->error;
+    }
+
+  private:
+    TestStream* const mStream;
+    std::atomic<size_t> mWorkerCycles = 0;
+    std::atomic<int> mPriority = ANDROID_PRIORITY_DEFAULT;
+};
+
+// 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(TestStream* 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:
+    TestStream 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());
+    worker.waitForAtLeastOneCycle();
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, WorkerError) {
+    ASSERT_TRUE(worker.start());
+    stream.error = true;
+    worker.waitForAtLeastOneCycle();
+    EXPECT_TRUE(worker.hasError());
+    EXPECT_TRUE(worker.hasNoWorkerCycleCalled(kWorkerIdleCheckTime));
+}
+
+TEST_P(StreamWorkerTest, PauseResume) {
+    ASSERT_TRUE(worker.start());
+    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());
+    worker.waitForAtLeastOneCycle();
+    EXPECT_FALSE(worker.hasError());
+    worker.pause();
+    worker.stop();
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, PauseAfterErrorIgnored) {
+    ASSERT_TRUE(worker.start());
+    stream.error = true;
+    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.error = true;
+    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());
+    worker.waitForAtLeastOneCycle();
+    EXPECT_FALSE(worker.hasError());
+    worker.pause();
+    EXPECT_FALSE(worker.hasError());
+    stream.error = true;
+    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.error = true;
+    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);
+    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();
+    worker.waitForAtLeastOneCycle();
+    EXPECT_EQ(priority, worker.getPriority());
+}
+
+INSTANTIATE_TEST_SUITE_P(StreamWorker, StreamWorkerTest, testing::Bool());
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index ad1d9c7..027d928 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -16,6 +16,8 @@
         "libstagefright_foundation",
         "android.media.audio.common.types-V1-ndk",
         "android.hardware.audio.core-V1-ndk",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
     ],
     export_include_dirs: ["include"],
     srcs: [
@@ -41,6 +43,8 @@
         "libstagefright_foundation",
         "android.media.audio.common.types-V1-ndk",
         "android.hardware.audio.core-V1-ndk",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
     ],
     static_libs: [
         "libaudioserviceexampleimpl",
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 5b4d48a..1c6f90a 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -27,7 +27,9 @@
 
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
+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::AudioIoFlags;
 using aidl::android::media::audio::common::AudioOffloadInfo;
 using aidl::android::media::audio::common::AudioOutputFlags;
@@ -36,6 +38,7 @@
 using aidl::android::media::audio::common::AudioPortExt;
 using aidl::android::media::audio::common::AudioProfile;
 using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::PcmType;
 
 namespace aidl::android::hardware::audio::core {
 
@@ -69,6 +72,49 @@
     return true;
 }
 
+constexpr size_t getPcmSampleSizeInBytes(PcmType pcm) {
+    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 AudioChannelLayout& layout) {
+    using Tag = 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>());
+        case Tag::layoutMask:
+            return __builtin_popcount(layout.get<Tag::layoutMask>());
+        case Tag::voiceMask:
+            return __builtin_popcount(layout.get<Tag::voiceMask>());
+    }
+    return 0;
+}
+
+size_t getFrameSizeInBytes(const AudioFormatDescription& format, const AudioChannelLayout& layout) {
+    if (format.type == AudioFormatType::PCM) {
+        return getPcmSampleSizeInBytes(format.pcm) * getChannelCount(layout);
+    }
+    // For non-PCM formats always use frame size of 1.
+    return 1;
+}
+
 bool findAudioProfile(const AudioPort& port, const AudioFormatDescription& format,
                       AudioProfile* profile) {
     if (auto profilesIt =
@@ -111,6 +157,78 @@
     erase_all_values(mPatches, erasedPatches);
 }
 
+ndk::ScopedAStatus Module::createStreamDescriptor(int32_t in_portConfigId,
+                                                  int64_t in_bufferSizeFrames,
+                                                  StreamDescriptor* out_descriptor) {
+    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 'createStreamDescriptor' is an internal 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);
+    }
+    (void)out_descriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+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();
+}
+
 internal::Configuration& Module::getConfig() {
     if (!mConfig) {
         mConfig.reset(new internal::Configuration(internal::getNullPrimaryConfiguration()));
@@ -336,98 +454,59 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Module::openInputStream(int32_t in_portConfigId,
-                                           const SinkMetadata& in_sinkMetadata,
-                                           std::shared_ptr<IStreamIn>* _aidl_return) {
-    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);
+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;
     }
-    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 (portIt->flags.getTag() != AudioIoFlags::Tag::input ||
-        portIt->ext.getTag() != AudioPortExt::Tag::mix) {
-        LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+    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);
     }
-    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 (auto status = createStreamDescriptor(in_args.portConfigId, in_args.bufferSizeFrames,
+                                             &_aidl_return->desc);
+        !status.isOk()) {
+        return status;
     }
-    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);
-    }
-    auto stream = ndk::SharedRefBase::make<StreamIn>(in_sinkMetadata);
-    mStreams.insert(portId, in_portConfigId, StreamWrapper(stream));
-    *_aidl_return = std::move(stream);
+    auto stream = ndk::SharedRefBase::make<StreamIn>(in_args.sinkMetadata);
+    mStreams.insert(port->id, in_args.portConfigId, StreamWrapper(stream));
+    _aidl_return->stream = std::move(stream);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Module::openOutputStream(int32_t in_portConfigId,
-                                            const SourceMetadata& in_sourceMetadata,
-                                            const std::optional<AudioOffloadInfo>& in_offloadInfo,
-                                            std::shared_ptr<IStreamOut>* _aidl_return) {
-    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);
+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;
     }
-    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 (portIt->flags.getTag() != AudioIoFlags::Tag::output ||
-        portIt->ext.getTag() != AudioPortExt::Tag::mix) {
-        LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+    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);
     }
-    if (portConfigIt->flags.has_value() &&
-        ((portConfigIt->flags.value().get<AudioIoFlags::Tag::output>() &
-          1 << static_cast<int32_t>(AudioOutputFlags::COMPRESS_OFFLOAD)) != 0) &&
-        !in_offloadInfo.has_value()) {
-        LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+    if ((port->flags.get<AudioIoFlags::Tag::output>() &
+         1 << static_cast<int32_t>(AudioOutputFlags::COMPRESS_OFFLOAD)) != 0 &&
+        !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);
     }
-    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 (auto status = createStreamDescriptor(in_args.portConfigId, in_args.bufferSizeFrames,
+                                             &_aidl_return->desc);
+        !status.isOk()) {
+        return status;
     }
-    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);
-    }
-    auto stream = ndk::SharedRefBase::make<StreamOut>(in_sourceMetadata, in_offloadInfo);
-    mStreams.insert(portId, in_portConfigId, StreamWrapper(stream));
-    *_aidl_return = std::move(stream);
+    auto stream = ndk::SharedRefBase::make<StreamOut>(in_args.sourceMetadata, in_args.offloadInfo);
+    mStreams.insert(port->id, in_args.portConfigId, StreamWrapper(stream));
+    _aidl_return->stream = std::move(stream);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -512,6 +591,10 @@
         }
     }
     *_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);
     if (existing == patches.end()) {
         _aidl_return->id = getConfig().nextPatchId++;
         patches.push_back(*_aidl_return);
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index e16b2c6..ab3e451 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -15,7 +15,6 @@
  */
 
 #define LOG_TAG "AHAL_Stream"
-#define LOG_NDEBUG 0
 #include <android-base/logging.h>
 
 #include "core-impl/Stream.h"
@@ -26,7 +25,9 @@
 
 namespace aidl::android::hardware::audio::core {
 
-StreamIn::StreamIn(const SinkMetadata& sinkMetadata) : mMetadata(sinkMetadata) {}
+StreamIn::StreamIn(const SinkMetadata& sinkMetadata) : mMetadata(sinkMetadata) {
+    LOG(DEBUG) << __func__;
+}
 
 ndk::ScopedAStatus StreamIn::close() {
     LOG(DEBUG) << __func__;
@@ -51,7 +52,9 @@
 
 StreamOut::StreamOut(const SourceMetadata& sourceMetadata,
                      const std::optional<AudioOffloadInfo>& offloadInfo)
-    : mMetadata(sourceMetadata), mOffloadInfo(offloadInfo) {}
+    : mMetadata(sourceMetadata), mOffloadInfo(offloadInfo) {
+    LOG(DEBUG) << __func__;
+}
 
 ndk::ScopedAStatus StreamOut::close() {
     LOG(DEBUG) << __func__;
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index 81a02ba..f7e14af 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -48,15 +48,15 @@
             int32_t in_portId,
             std::vector<::aidl::android::hardware::audio::core::AudioRoute>* _aidl_return) override;
     ndk::ScopedAStatus openInputStream(
-            int32_t in_portConfigId,
-            const ::aidl::android::hardware::audio::common::SinkMetadata& in_sinkMetadata,
-            std::shared_ptr<IStreamIn>* _aidl_return) override;
+            const ::aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments&
+                    in_args,
+            ::aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn* _aidl_return)
+            override;
     ndk::ScopedAStatus openOutputStream(
-            int32_t in_portConfigId,
-            const ::aidl::android::hardware::audio::common::SourceMetadata& in_sourceMetadata,
-            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
-                    in_offloadInfo,
-            std::shared_ptr<IStreamOut>* _aidl_return) override;
+            const ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments&
+                    in_args,
+            ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn* _aidl_return)
+            override;
     ndk::ScopedAStatus setAudioPatch(const AudioPatch& in_requested,
                                      AudioPatch* _aidl_return) override;
     ndk::ScopedAStatus setAudioPortConfig(
@@ -69,9 +69,21 @@
   private:
     void cleanUpPatch(int32_t patchId);
     void cleanUpPatches(int32_t portConfigId);
+    ndk::ScopedAStatus createStreamDescriptor(
+            int32_t in_portConfigId, int64_t in_bufferSizeFrames,
+            ::aidl::android::hardware::audio::core::StreamDescriptor* out_descriptor);
+    ndk::ScopedAStatus findPortIdForNewStream(
+            int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port);
     internal::Configuration& getConfig();
     void registerPatch(const AudioPatch& patch);
 
+    // This value is used for all AudioPatches.
+    static constexpr int32_t kMinimumStreamBufferSizeFrames = 16;
+    // This value is used for all AudioPatches.
+    static constexpr int32_t kLatencyMs = 10;
+    // The maximum stream buffer size is 1 GiB = 2 ** 30 bytes;
+    static constexpr int32_t kMaximumStreamBufferSizeBytes = 1 << 30;
+
     std::unique_ptr<internal::Configuration> mConfig;
     ModuleDebug mDebug;
     // ids of ports created at runtime via 'connectExternalDevice'.
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index cd5915b..75ff37f 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -23,6 +23,8 @@
     static_libs: [
         "android.hardware.audio.common-V1-ndk",
         "android.hardware.audio.core-V1-ndk",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
         "android.media.audio.common.types-V1-ndk",
     ],
     test_suites: [
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp
index bb24365..0ecc057 100644
--- a/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp
@@ -16,6 +16,7 @@
 
 #include <algorithm>
 #include <condition_variable>
+#include <limits>
 #include <memory>
 #include <mutex>
 #include <optional>
@@ -48,6 +49,7 @@
 using aidl::android::hardware::audio::core::IStreamIn;
 using aidl::android::hardware::audio::core::IStreamOut;
 using aidl::android::hardware::audio::core::ModuleDebug;
+using aidl::android::hardware::audio::core::StreamDescriptor;
 using aidl::android::media::audio::common::AudioContentType;
 using aidl::android::media::audio::common::AudioDevice;
 using aidl::android::media::audio::common::AudioDeviceAddress;
@@ -225,6 +227,9 @@
 
 class AudioCoreModule : public testing::TestWithParam<std::string> {
   public:
+    // The default buffer size is used mostly for negative tests.
+    static constexpr int kDefaultBufferSize = 256;
+
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(ConnectToService());
         debug.flags().simulateDeviceConnections = true;
@@ -382,13 +387,14 @@
         }
     }
     void SetUpPortConfig(IModule* module) { ASSERT_NO_FATAL_FAILURE(mPortConfig.SetUp(module)); }
-    ScopedAStatus SetUpNoChecks(IModule* module) {
-        return SetUpNoChecks(module, mPortConfig.get());
+    ScopedAStatus SetUpNoChecks(IModule* module, long bufferSize) {
+        return SetUpNoChecks(module, mPortConfig.get(), bufferSize);
     }
-    ScopedAStatus SetUpNoChecks(IModule* module, const AudioPortConfig& portConfig);
-    void SetUp(IModule* module) {
+    ScopedAStatus SetUpNoChecks(IModule* module, const AudioPortConfig& portConfig,
+                                long bufferSize);
+    void SetUp(IModule* module, long bufferSize) {
         ASSERT_NO_FATAL_FAILURE(SetUpPortConfig(module));
-        ScopedAStatus status = SetUpNoChecks(module);
+        ScopedAStatus status = SetUpNoChecks(module, bufferSize);
         ASSERT_EQ(EX_NONE, status.getExceptionCode())
                 << status << "; port config id " << getPortId();
         ASSERT_NE(nullptr, mStream) << "; port config id " << getPortId();
@@ -401,6 +407,7 @@
   private:
     WithAudioPortConfig mPortConfig;
     std::shared_ptr<Stream> mStream;
+    StreamDescriptor mDescriptor;
 };
 
 SinkMetadata GenerateSinkMetadata(const AudioPortConfig& portConfig) {
@@ -415,8 +422,19 @@
 
 template <>
 ScopedAStatus WithStream<IStreamIn>::SetUpNoChecks(IModule* module,
-                                                   const AudioPortConfig& portConfig) {
-    return module->openInputStream(portConfig.id, GenerateSinkMetadata(portConfig), &mStream);
+                                                   const AudioPortConfig& portConfig,
+                                                   long bufferSize) {
+    aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments args;
+    args.portConfigId = portConfig.id;
+    args.sinkMetadata = GenerateSinkMetadata(portConfig);
+    args.bufferSizeFrames = bufferSize;
+    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);
+    }
+    return status;
 }
 
 SourceMetadata GenerateSourceMetadata(const AudioPortConfig& portConfig) {
@@ -432,10 +450,20 @@
 
 template <>
 ScopedAStatus WithStream<IStreamOut>::SetUpNoChecks(IModule* module,
-                                                    const AudioPortConfig& portConfig) {
-    return module->openOutputStream(portConfig.id, GenerateSourceMetadata(portConfig),
-                                    ModuleConfig::generateOffloadInfoIfNeeded(portConfig),
-                                    &mStream);
+                                                    const AudioPortConfig& portConfig,
+                                                    long bufferSize) {
+    aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
+    args.portConfigId = portConfig.id;
+    args.sourceMetadata = GenerateSourceMetadata(portConfig);
+    args.offloadInfo = ModuleConfig::generateOffloadInfoIfNeeded(portConfig);
+    args.bufferSizeFrames = bufferSize;
+    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);
+    }
+    return status;
 }
 
 class WithAudioPatch {
@@ -467,6 +495,10 @@
         ASSERT_EQ(EX_NONE, status.getExceptionCode())
                 << status << "; 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; }
@@ -739,18 +771,24 @@
     ASSERT_NO_FATAL_FAILURE(GetAllPortConfigIds(&portConfigIds));
     for (const auto portConfigId : GetNonExistentIds(portConfigIds)) {
         {
-            std::shared_ptr<IStreamIn> stream;
-            ScopedAStatus status = module->openInputStream(portConfigId, {}, &stream);
+            aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments args;
+            args.portConfigId = portConfigId;
+            args.bufferSizeFrames = kDefaultBufferSize;
+            aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn ret;
+            ScopedAStatus status = module->openInputStream(args, &ret);
             EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode())
                     << status << " openInputStream returned for port config ID " << portConfigId;
-            EXPECT_EQ(nullptr, stream);
+            EXPECT_EQ(nullptr, ret.stream);
         }
         {
-            std::shared_ptr<IStreamOut> stream;
-            ScopedAStatus status = module->openOutputStream(portConfigId, {}, {}, &stream);
+            aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
+            args.portConfigId = portConfigId;
+            args.bufferSizeFrames = kDefaultBufferSize;
+            aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
+            ScopedAStatus status = module->openOutputStream(args, &ret);
             EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode())
                     << status << " openOutputStream returned for port config ID " << portConfigId;
-            EXPECT_EQ(nullptr, stream);
+            EXPECT_EQ(nullptr, ret.stream);
         }
     }
 }
@@ -1120,7 +1158,7 @@
         std::shared_ptr<Stream> heldStream;
         {
             WithStream<Stream> stream(portConfig.value());
-            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get()));
+            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSize));
             heldStream = stream.getSharedPointer();
         }
         ScopedAStatus status = heldStream->close();
@@ -1132,10 +1170,43 @@
         const auto allPortConfigs = moduleConfig->getPortConfigsForMixPorts(IsInput<Stream>());
         for (const auto& portConfig : allPortConfigs) {
             WithStream<Stream> stream(portConfig);
-            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get()));
+            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSize));
         }
     }
 
+    void OpenInvalidBufferSize() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IsInput<Stream>());
+        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()));
+        // The buffer size of 1 frame should be impractically small, and thus
+        // less than any minimum buffer size suggested by any HAL.
+        for (long bufferSize : std::array<long, 4>{-1, 0, 1, std::numeric_limits<long>::max()}) {
+            ScopedAStatus status = stream.SetUpNoChecks(module.get(), bufferSize);
+            EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode())
+                    << status << " open" << direction(true) << "Stream returned for " << bufferSize
+                    << " buffer size";
+            EXPECT_EQ(nullptr, stream.get());
+        }
+    }
+
+    void OpenInvalidDirection() {
+        // Important! The direction of the port config must be reversed.
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(!IsInput<Stream>());
+        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()));
+        ScopedAStatus status = stream.SetUpNoChecks(module.get(), kDefaultBufferSize);
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode())
+                << status << " open" << direction(true) << "Stream returned for port config ID "
+                << stream.getPortId();
+        EXPECT_EQ(nullptr, stream.get());
+    }
+
     void OpenOverMaxCount() {
         constexpr bool isInput = IsInput<Stream>();
         auto ports = moduleConfig->getMixPorts(isInput);
@@ -1158,10 +1229,10 @@
                 streamWraps[i].emplace(portConfigs[i]);
                 WithStream<Stream>& stream = streamWraps[i].value();
                 if (i < maxStreamCount) {
-                    ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get()));
+                    ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSize));
                 } else {
                     ASSERT_NO_FATAL_FAILURE(stream.SetUpPortConfig(module.get()));
-                    ScopedAStatus status = stream.SetUpNoChecks(module.get());
+                    ScopedAStatus status = stream.SetUpNoChecks(module.get(), kDefaultBufferSize);
                     EXPECT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode())
                             << status << " open" << direction(true)
                             << "Stream returned for port config ID " << stream.getPortId()
@@ -1175,21 +1246,6 @@
         }
     }
 
-    void OpenInvalidDirection() {
-        // Important! The direction of the port config must be reversed.
-        const auto portConfig = moduleConfig->getSingleConfigForMixPort(!IsInput<Stream>());
-        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()));
-        ScopedAStatus status = stream.SetUpNoChecks(module.get());
-        EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode())
-                << status << " open" << direction(true) << "Stream returned for port config ID "
-                << stream.getPortId();
-        EXPECT_EQ(nullptr, stream.get());
-    }
-
     void OpenTwiceSamePortConfig() {
         const auto portConfig = moduleConfig->getSingleConfigForMixPort(IsInput<Stream>());
         if (!portConfig.has_value()) {
@@ -1204,7 +1260,7 @@
             GTEST_SKIP() << "No mix port for attached devices";
         }
         WithStream<Stream> stream(portConfig.value());
-        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get()));
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSize));
         ScopedAStatus status = module->resetAudioPortConfig(stream.getPortId());
         EXPECT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode())
                 << status << " returned for port config ID " << stream.getPortId();
@@ -1212,9 +1268,10 @@
 
     void OpenTwiceSamePortConfigImpl(const AudioPortConfig& portConfig) {
         WithStream<Stream> stream1(portConfig);
-        ASSERT_NO_FATAL_FAILURE(stream1.SetUp(module.get()));
+        ASSERT_NO_FATAL_FAILURE(stream1.SetUp(module.get(), kDefaultBufferSize));
         WithStream<Stream> stream2;
-        ScopedAStatus status = stream2.SetUpNoChecks(module.get(), stream1.getPortConfig());
+        ScopedAStatus status =
+                stream2.SetUpNoChecks(module.get(), stream1.getPortConfig(), kDefaultBufferSize);
         EXPECT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode())
                 << status << " when opening " << direction(false)
                 << " stream twice for the same port config ID " << stream1.getPortId();
@@ -1238,6 +1295,7 @@
 
 TEST_IO_STREAM(CloseTwice);
 TEST_IO_STREAM(OpenAllConfigs);
+TEST_IO_STREAM(OpenInvalidBufferSize);
 TEST_IO_STREAM(OpenInvalidDirection);
 TEST_IO_STREAM(OpenOverMaxCount);
 TEST_IO_STREAM(OpenTwiceSamePortConfig);
@@ -1277,10 +1335,14 @@
     const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, *offloadPortIt);
     ASSERT_TRUE(portConfig.has_value())
             << "No profiles specified for the compressed offload mix port";
+    StreamDescriptor descriptor;
     std::shared_ptr<IStreamOut> ignored;
-    ScopedAStatus status = module->openOutputStream(portConfig.value().id,
-                                                    GenerateSourceMetadata(portConfig.value()),
-                                                    {} /* offloadInfo */, &ignored);
+    aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
+    args.portConfigId = portConfig.value().id;
+    args.sourceMetadata = GenerateSourceMetadata(portConfig.value());
+    args.bufferSizeFrames = kDefaultBufferSize;
+    aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
+    ScopedAStatus status = module->openOutputStream(args, &ret);
     EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode())
             << status
             << " returned when no offload info is provided for a compressed offload mix port";
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 44d3cbd..4b76a0b 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -18,6 +18,7 @@
 #include <numeric>
 
 #include <android-base/chrono_utils.h>
+#include <cutils/properties.h>
 
 #include "Generators.h"
 
@@ -895,16 +896,60 @@
     }
 };
 
+class OffloadCallbacks : public IStreamOutCallback {
+  public:
+    Return<void> onDrainReady() override {
+        ALOGI("onDrainReady");
+        {
+            std::lock_guard lg(mLock);
+            mOnDrainReady = true;
+        }
+        mCondVar.notify_one();
+        return {};
+    }
+    Return<void> onWriteReady() override { return {}; }
+    Return<void> onError() override {
+        ALOGW("onError");
+        {
+            std::lock_guard lg(mLock);
+            mOnError = true;
+        }
+        mCondVar.notify_one();
+        return {};
+    }
+    bool waitForDrainReadyOrError() {
+        std::unique_lock l(mLock);
+        if (!mOnDrainReady && !mOnError) {
+            mCondVar.wait(l, [&]() { return mOnDrainReady || mOnError; });
+        }
+        const bool success = !mOnError;
+        mOnDrainReady = mOnError = false;
+        return success;
+    }
+
+  private:
+    std::mutex mLock;
+    bool mOnDrainReady = false;
+    bool mOnError = false;
+    std::condition_variable mCondVar;
+};
+
 TEST_P(CompressedOffloadOutputStreamTest, Mp3FormatGaplessOffload) {
     doc::test("Check that compressed offload mix ports for MP3 implement gapless offload");
     const auto& flags = getOutputFlags();
+    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+    // See test instantiation, only offload MP3 mix ports are used.
     if (std::find_if(flags.begin(), flags.end(), [](const auto& flag) {
             return flag == toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD);
         }) == flags.end()) {
-        GTEST_SKIP() << "Compressed offload mix port does not support gapless offload";
+        if (isNewDeviceLaunchingOnTPlus) {
+            FAIL() << "New devices launching on Android T+ must support gapless offload, "
+                   << "see VSR-4.3-001";
+        } else {
+            GTEST_SKIP() << "Compressed offload mix port does not support gapless offload";
+        }
     }
-    // FIXME: The presentation position is not updated if there is no zero padding in data.
-    std::vector<uint8_t> offloadData(stream->getBufferSize());
+    std::vector<uint8_t> offloadData;
     ASSERT_NO_FATAL_FAILURE(loadData("/data/local/tmp/sine882hz3s.mp3", &offloadData));
     ASSERT_FALSE(offloadData.empty());
     ASSERT_NO_FATAL_FAILURE(createPatchIfNeeded());
@@ -914,38 +959,70 @@
     const int delay = 576 + 1000;
     const int padding = 756 + 1000;
     const int durationMs = 3000 - 44;
-    // StreamWriter plays 'offloadData' in a loop, possibly using multiple calls to 'write',
-    // this depends on the relative sizes of 'offloadData' and the HAL buffer. Writer calls
-    // 'onDataWrap' callback each time it wraps around the buffer.
+    auto start = std::chrono::steady_clock::now();
+    auto callbacks = sp<OffloadCallbacks>::make();
+    std::mutex presentationEndLock;
+    std::vector<float> presentationEndTimes;
+    // StreamWriter plays 'offloadData' in a loop, possibly using multiple calls to 'write', this
+    // depends on the relative sizes of 'offloadData' and the HAL buffer. Writer calls 'onDataStart'
+    // each time it starts writing the buffer from the beginning, and 'onDataWrap' callback each
+    // time it wraps around the buffer.
     StreamWriter writer(
-            stream.get(), stream->getBufferSize(), std::move(offloadData), [&]() /* onDataWrap */ {
-                Parameters::set(stream,
-                                {{AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, std::to_string(delay)},
+            stream.get(), stream->getBufferSize(), std::move(offloadData),
+            [&]() /* onDataStart */ { start = std::chrono::steady_clock::now(); },
+            [&]() /* onDataWrap */ {
+                Return<Result> ret(Result::OK);
+                // Decrease the volume since the test plays a loud sine wave.
+                ret = stream->setVolume(0.1, 0.1);
+                if (!ret.isOk() || ret != Result::OK) {
+                    ALOGE("%s: setVolume failed: %s", __func__, toString(ret).c_str());
+                    return false;
+                }
+                ret = Parameters::set(
+                        stream, {{AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, std::to_string(delay)},
                                  {AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES, std::to_string(padding)}});
-                stream->drain(AudioDrain::EARLY_NOTIFY);
+                if (!ret.isOk() || ret != Result::OK) {
+                    ALOGE("%s: setParameters failed: %s", __func__, toString(ret).c_str());
+                    return false;
+                }
+                ret = stream->drain(AudioDrain::EARLY_NOTIFY);
+                if (!ret.isOk() || ret != Result::OK) {
+                    ALOGE("%s: drain failed: %s", __func__, toString(ret).c_str());
+                    return false;
+                }
+                // FIXME: On some SoCs intermittent errors are possible, ignore them.
+                if (callbacks->waitForDrainReadyOrError()) {
+                    const float duration = std::chrono::duration_cast<std::chrono::milliseconds>(
+                                                   std::chrono::steady_clock::now() - start)
+                                                   .count();
+                    std::lock_guard lg(presentationEndLock);
+                    presentationEndTimes.push_back(duration);
+                }
+                return true;
             });
+    ASSERT_OK(stream->setCallback(callbacks));
     ASSERT_TRUE(writer.start());
-    ASSERT_TRUE(writer.waitForAtLeastOneCycle());
-    // Decrease the volume since the test plays a loud sine wave.
-    ASSERT_OK(stream->setVolume(0.1, 0.1));
     // How many times to loop the track so that the sum of gapless delay and padding from
     // the first presentation end to the last is at least 'presentationeEndPrecisionMs'.
     const int playbackNumber = (int)(significantSampleNumber / ((float)delay + padding) + 1);
-    std::vector<float> presentationEndTimes;
-    uint64_t previousPosition = std::numeric_limits<uint64_t>::max();
-    for (int i = 0; i < playbackNumber; ++i) {
-        const auto start = std::chrono::steady_clock::now();
-        ASSERT_NO_FATAL_FAILURE(
-                waitForPresentationPositionAdvance(writer, &previousPosition, &previousPosition));
-        presentationEndTimes.push_back(std::chrono::duration_cast<std::chrono::milliseconds>(
-                                               std::chrono::steady_clock::now() - start)
-                                               .count());
+    for (bool done = false; !done;) {
+        usleep(presentationeEndPrecisionMs * 1000);
+        {
+            std::lock_guard lg(presentationEndLock);
+            done = presentationEndTimes.size() >= playbackNumber;
+        }
+        ASSERT_FALSE(writer.hasError()) << "Recent write or drain operation has failed";
     }
     const float avgDuration =
             std::accumulate(presentationEndTimes.begin(), presentationEndTimes.end(), 0.0) /
             presentationEndTimes.size();
-    EXPECT_NEAR(durationMs, avgDuration, presentationeEndPrecisionMs * 0.1);
+    std::stringstream observedEndTimes;
+    std::copy(presentationEndTimes.begin(), presentationEndTimes.end(),
+              std::ostream_iterator<float>(observedEndTimes, ", "));
+    EXPECT_NEAR(durationMs, avgDuration, presentationeEndPrecisionMs * 0.1)
+            << "Observed durations: " << observedEndTimes.str();
     writer.stop();
+    EXPECT_OK(stream->clearCallback());
     releasePatchIfNeeded();
 }
 
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index 5b0a7f2..daed7a8 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -34,6 +34,7 @@
     ],
     shared_libs: [
         "libbinder",
+        "libcutils",
         "libfmq",
         "libxml2",
     ],
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 6c5584d..e46e5b4 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -938,12 +938,13 @@
     StreamWriter(IStreamOut* stream, size_t bufferSize)
         : mStream(stream), mBufferSize(bufferSize), mData(mBufferSize) {}
     StreamWriter(IStreamOut* stream, size_t bufferSize, std::vector<uint8_t>&& data,
-                 std::function<void()> onDataWrap)
+                 std::function<void()> onDataStart, std::function<bool()> onDataWrap)
         : mStream(stream),
           mBufferSize(bufferSize),
           mData(std::move(data)),
+          mOnDataStart(onDataStart),
           mOnDataWrap(onDataWrap) {
-        ALOGW("StreamWriter data size: %d", (int)mData.size());
+        ALOGI("StreamWriter data size: %d", (int)mData.size());
     }
     ~StreamWriter() {
         stop();
@@ -1010,6 +1011,7 @@
             ALOGE("command message queue write failed");
             return false;
         }
+        if (mDataPosition == 0) mOnDataStart();
         const size_t dataSize = std::min(mData.size() - mDataPosition, mDataMQ->availableToWrite());
         bool success = mDataMQ->write(mData.data() + mDataPosition, dataSize);
         ALOGE_IF(!success, "data message queue write failed");
@@ -1040,7 +1042,9 @@
             ALOGE("bad wait status: %d", ret);
             success = false;
         }
-        if (success && mDataPosition == 0) mOnDataWrap();
+        if (success && mDataPosition == 0) {
+            success = mOnDataWrap();
+        }
         return success;
     }
 
@@ -1048,7 +1052,8 @@
     IStreamOut* const mStream;
     const size_t mBufferSize;
     std::vector<uint8_t> mData;
-    std::function<void()> mOnDataWrap = []() {};
+    std::function<void()> mOnDataStart = []() {};
+    std::function<bool()> mOnDataWrap = []() { return true; };
     size_t mDataPosition = 0;
     std::unique_ptr<CommandMQ> mCommandMQ;
     std::unique_ptr<DataMQ> mDataMQ;
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index 3baafc9..def3a3f 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -238,12 +238,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 +271,7 @@
             *valueData = halParam->data + valueOffsetFromData;
         }
     }
-    return halParamBuffer;
+    return true;
 }
 
 Result Effect::analyzeCommandStatus(const char* commandName, const char* context, status_t status) {
@@ -314,11 +329,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(
@@ -472,8 +491,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]);
 }
diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h
index 011544d..f0b65df 100644
--- a/audio/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/Effect.h
@@ -211,8 +211,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/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index e59423f..ffa4c56 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -623,6 +623,23 @@
     EXPECT_TRUE(ret.isOk());
 }
 
+TEST_P(AudioEffectHidlTest, GetParameterInvalidMaxReplySize) {
+    description("Verify that GetParameter caps the maximum reply size");
+    // 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(
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++/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++/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/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/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/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/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index fa0b791..da8416c 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -7,6 +7,15 @@
       "name": "VehicleHalDefaultConfigTest"
     },
     {
+      "name": "VehicleHalDefaultConfigTestEnableTestProperties"
+    },
+    {
+      "name": "JsonConfigLoaderUnitTest"
+    },
+    {
+      "name": "JsonConfigLoaderUnitTestEnableTestProperties"
+    },
+    {
       "name": "VehicleHalVehicleUtilsTest"
     },
     {
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
index e8a6c85..1cf8aff 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -542,7 +542,7 @@
      */
     TRACTION_CONTROL_ACTIVE = 0x040B + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /*
+    /**
      * HVAC Properties
      *
      * Additional rules for mapping a zoned HVAC property (except
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index 4d37cd3..14a694d 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -77,7 +77,7 @@
         {VehicleProperty::IGNITION_STATE, VehiclePropertyAccess::READ},
         {VehicleProperty::ABS_ACTIVE, VehiclePropertyAccess::READ},
         {VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess::READ},
-        {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ},
+        {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},
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
index fdf6c64..0a17ba1 100644
--- a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -69,7 +69,7 @@
         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.HVAC_FAN_SPEED, VehiclePropertyAccess.READ),
+        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),
diff --git a/automotive/vehicle/aidl/impl/default_config/Android.bp b/automotive/vehicle/aidl/impl/default_config/Android.bp
index 0feaf23..aa22d87 100644
--- a/automotive/vehicle/aidl/impl/default_config/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/Android.bp
@@ -25,7 +25,13 @@
     export_include_dirs: ["include"],
     defaults: ["VehicleHalDefaults"],
     static_libs: ["VehicleHalUtils"],
-    header_libs: ["VehicleHalTestUtilHeaders"],
+    header_libs: [
+        "VehicleHalJsonConfigLoaderHeaders",
+        "VehicleHalTestUtilHeaders",
+    ],
     export_static_lib_headers: ["VehicleHalUtils"],
-    export_header_lib_headers: ["VehicleHalTestUtilHeaders"],
+    export_header_lib_headers: [
+        "VehicleHalTestUtilHeaders",
+        "VehicleHalJsonConfigLoaderHeaders",
+    ],
 }
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..e6b7d14
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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::ChangeModeForVehicleProperty;
+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::GsrComplianceRequirementType;
+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 ::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},
+        {"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_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_SWITCH_AUTO", LIGHT_SWITCH_AUTO},
+        {"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},
+        {"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["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["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);
+        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..9ff8c1b
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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";
+}
+
+}  // 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..f4ce402
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -0,0 +1,1669 @@
+{
+    "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_MAKE",
+            "defaultValue": {
+                "stringValue": "Toy Vehicle"
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MODEL",
+            "defaultValue": {
+                "stringValue": "Speedy Model"
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MODEL_YEAR",
+            "defaultValue": {
+                "int32Values": [
+                    2020
+                ]
+            }
+        },
+        {
+            "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::VEHICLE_SPEED_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::KILOMETERS_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_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_OCCUPANCY",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            "VehicleSeatOccupancyState::VACANT"
+                        ]
+                    },
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            "VehicleSeatOccupancyState::VACANT"
+                        ]
+                    },
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                }
+            ]
+        },
+        {
+            "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_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::FUEL_LEVEL_LOW",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::LITER"
+                ]
+            },
+            "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_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_POWER_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ],
+            "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::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_RECIRC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_AUTO_RECIRC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_AC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_MAX_AC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_AUTO_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_DUAL_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_FAN_SPEED",
+            "defaultValue": {
+                "int32Values": [
+                    3
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_FAN_DIRECTION",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleHvacFanDirection::FACE"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE",
+            "defaultValue": {
+                "int32Values": [
+                    "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::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "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
+                }
+            ],
+            "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
+                }
+            ],
+            "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_SET",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            16.0
+                        ]
+                    },
+                    "areaId": 49,
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 32.0
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            20.0
+                        ]
+                    },
+                    "areaId": 68,
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 32.0
+                }
+            ],
+            "configArray": [
+                160,
+                280,
+                5,
+                605,
+                825,
+                10
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION",
+            "defaultValue": {
+                "floatValues": [
+                    66.19999694824219,
+                    49.0,
+                    19.0,
+                    66.5
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ENV_OUTSIDE_TEMPERATURE",
+            "defaultValue": {
+                "floatValues": [
+                    25.0
+                ]
+            },
+            "maxSampleRate": 2.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    49
+                ]
+            },
+            "configArray": [
+                49,
+                48
+            ]
+        },
+        {
+            "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::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_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::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::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::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::EVS_SERVICE_REQUEST",
+            "defaultValue": {
+                "int32Values": [
+                    "EvsServiceType::REARVIEW",
+                    "EvsServiceState::OFF"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_MAP_SERVICE"
+        },
+        {
+            "property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "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_THROUGH_SYSTEM_IMAGE"
+                ]
+            }
+        }
+    ]
+}
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..0e3fc5e
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/README.md
@@ -0,0 +1,151 @@
+# 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
+
+* 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..33c6cc2
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/TestProperties.json
@@ -0,0 +1,204 @@
+{
+    "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": "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
index 46b9a89..8c6fa1b 100644
--- a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
+++ b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
@@ -17,6 +17,7 @@
 #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 <ConfigDeclaration.h>
 #include <PropertyUtils.h>
 #include <TestPropertyUtils.h>
 #include <VehicleHalTypes.h>
@@ -41,6 +42,7 @@
 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;
@@ -55,17 +57,6 @@
 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 =
                  {
@@ -183,6 +174,176 @@
                  },
          .initialValue = {.int32Values = {toInt(VehicleUnit::KILOWATT_HOUR)}}},
 
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_BUCKLED),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_HEIGHT_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {10}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_HEIGHT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_FORE_AFT_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_FORE_AFT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_1_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_2_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
         {.config =
                  {
                          .prop = toInt(VehicleProperty::SEAT_OCCUPANCY),
@@ -364,8 +525,9 @@
                          .prop = toInt(VehicleProperty::VEHICLE_CURB_WEIGHT),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::STATIC,
+                         .configArray = {/*gross weight kg=*/2948},
                  },
-         .initialValue = {.int32Values = {30}}},
+         .initialValue = {.int32Values = {2211 /*kg*/}}},
 
         {.config =
                  {
@@ -481,6 +643,15 @@
 
         {.config =
                  {
+                         .prop = toInt(
+                                 VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME),
+                         .access = VehiclePropertyAccess::READ_WRITE,
+                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                 },
+         .initialValue = {.int32Values = {1}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::HW_KEY_INPUT),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -644,6 +815,17 @@
                                     }}},
          .initialValue = {.int32Values = {0}}},  // +ve values for heating and -ve for cooling
 
+        {.config = {.prop = toInt(VehicleProperty::HVAC_SIDE_MIRROR_HEAT),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{
+                            .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT) |
+                                      toInt(VehicleAreaMirror::DRIVER_RIGHT),
+                            .minInt32Value = 0,
+                            .maxInt32Value = 2,
+                    }}},
+         .initialValue = {.int32Values = {0}}},
+
         {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
                     .access = VehiclePropertyAccess::READ_WRITE,
                     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -953,14 +1135,7 @@
                  },
          .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}}},
-
+        // FOG_LIGHTS_SWITCH must not be implemented when FRONT_FOG_LIGHTS_SWITCH is implemented
         {.config =
                  {
                          .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_SWITCH),
@@ -969,6 +1144,7 @@
                  },
          .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
 
+        // FOG_LIGHTS_SWITCH must not be implemented when REAR_FOG_LIGHTS_SWITCH is implemented
         {.config =
                  {
                          .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_SWITCH),
@@ -1059,7 +1235,7 @@
                  {
                          .prop = toInt(VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION),
                          .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                         .changeMode = VehiclePropertyChangeMode::STATIC,
                          .configArray = {kMixedTypePropertyForTest,
                                          toInt(VehicleVendorPermission::
                                                        PERMISSION_GET_VENDOR_CATEGORY_INFO),
@@ -1103,8 +1279,8 @@
                 .config =
                         {
                                 .prop = toInt(VehicleProperty::REMOVE_USER),
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                                .access = VehiclePropertyAccess::WRITE,
+                                .changeMode = VehiclePropertyChangeMode::STATIC,
                         },
         },
         {
@@ -1327,8 +1503,6 @@
 // public namespace
 namespace defaultconfig {
 
-typedef defaultconfig_impl::ConfigDeclaration ConfigDeclaration;
-
 inline constexpr const std::vector<ConfigDeclaration>& getDefaultConfigs() {
     return defaultconfig_impl::kVehicleProperties;
 }
diff --git a/automotive/vehicle/aidl/impl/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
index 771472c..b05d47c 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
@@ -24,11 +24,53 @@
     defaults: ["VehicleHalDefaults"],
     srcs: ["*.cpp"],
     static_libs: [
+        "VehicleHalJsonConfigLoader",
         "VehicleHalUtils",
+        "libgmock",
         "libgtest",
     ],
     header_libs: [
+        // TODO(b/238685398): Remove this once we deprecate DefaultConfig.h
         "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: [
+        // TODO(b/238685398): Remove this once we deprecate DefaultConfig.h
+        "-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING",
+        "-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
+    ],
+    header_libs: [
+        // TODO(b/238685398): Remove this once we deprecate DefaultConfig.h
+        "VehicleHalDefaultConfig",
+        "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..f0ab806 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
@@ -15,26 +15,95 @@
  */
 
 #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();
+}
+
+// TODO(b/238685398): Remove this test after we deprecate DefaultConfig.h
+TEST(DefaultConfigTest, TestCompatibleWithDefaultConfigHeader) {
+    auto configsFromHeaderFile = defaultconfig::getDefaultConfigs();
+
+    std::vector<ConfigDeclaration> configsFromJson;
+    JsonConfigLoader loader;
+    for (const char* file :
+         std::vector<const char*>({kDefaultPropertiesConfigFile, kTestPropertiesConfigFile,
+                                   kVendorClusterTestPropertiesConfigFile})) {
+        auto result = loadConfig(loader, file);
+        ASSERT_TRUE(result.ok()) << result.error().message();
+        for (auto& [propId, configDeclaration] : result.value()) {
+            configsFromJson.push_back(configDeclaration);
+        }
+    }
+
+    ASSERT_EQ(configsFromHeaderFile.size(), configsFromJson.size());
+    ASSERT_THAT(configsFromHeaderFile, UnorderedElementsAreArray(configsFromJson));
+}
+
+#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/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 8cc19b1..1636cb6 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -18,11 +18,12 @@
 #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>
@@ -32,9 +33,9 @@
 #include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
 
-#include <map>
 #include <memory>
 #include <mutex>
+#include <unordered_map>
 #include <vector>
 
 namespace android {
@@ -49,7 +50,8 @@
 
     FakeVehicleHardware();
 
-    explicit FakeVehicleHardware(std::unique_ptr<VehiclePropValuePool> valuePool);
+    FakeVehicleHardware(std::string defaultConfigDir, std::string overrideConfigDir,
+                        bool forceOverride);
 
     ~FakeVehicleHardware();
 
@@ -151,17 +153,23 @@
                                   aidl::android::hardware::automotive::vehicle::SetValueRequest>
             mPendingSetValueRequests;
 
+    const std::string mDefaultConfigDir;
+    const std::string mOverrideConfigDir;
+    const bool mForceOverride;
+
+    // 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(
@@ -185,6 +193,8 @@
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
     bool isHvacPropAndHvacNotAvailable(int32_t propId);
 
+    std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations();
+
     std::string dumpAllProperties();
     std::string dumpOnePropertyByConfig(
             int rowNumber,
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 7c451fe..d87e5aa 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -19,7 +19,6 @@
 
 #include "FakeVehicleHardware.h"
 
-#include <DefaultConfig.h>
 #include <FakeObd2Frame.h>
 #include <JsonFakeValueGenerator.h>
 #include <LinearFakeValueGenerator.h>
@@ -27,6 +26,8 @@
 #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>
@@ -74,9 +75,16 @@
 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";
-const char* POWER_STATE_REQ_CONFIG_PROPERTY = "ro.vendor.fake_vhal.ap_power_state_req.config";
+// 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";
 
 // A list of supported options for "--set" command.
 const std::unordered_set<std::string> SET_PROP_OPTIONS = {
@@ -97,7 +105,7 @@
 
 }  // namespace
 
-void FakeVehicleHardware::storePropInitialValue(const defaultconfig::ConfigDeclaration& config) {
+void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config) {
     const VehiclePropConfig& vehiclePropConfig = config.config;
     int propId = vehiclePropConfig.prop;
 
@@ -139,10 +147,11 @@
 }
 
 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)),
@@ -150,7 +159,10 @@
       mGeneratorHub(new GeneratorHub(
               [this](const VehiclePropValue& value) { eventFromVehicleBus(value); })),
       mPendingGetValueRequests(this),
-      mPendingSetValueRequests(this) {
+      mPendingSetValueRequests(this),
+      mDefaultConfigDir(defaultConfigDir),
+      mOverrideConfigDir(overrideConfigDir),
+      mForceOverride(forceOverride) {
     init();
 }
 
@@ -160,9 +172,19 @@
     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 == toInt(VehicleProperty::AP_POWER_STATE_REQ)) {
@@ -178,15 +200,18 @@
             // 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); });
@@ -408,7 +433,7 @@
             *isSpecialValue = true;
             return mFakeObd2Frame->clearObd2FreezeFrames(value);
 
-#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):
@@ -436,7 +461,7 @@
                        << getErrorMsg(writeResult);
             }
             return {};
-#endif  // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+#endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
 
         default:
             break;
@@ -1264,33 +1289,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);
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 cfd6577..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,6 +41,9 @@
         "libjsoncpp",
     ],
     data: [
+        ":VehicleHalDefaultProperties_JSON",
+        ":VehicleHalTestProperties_JSON",
+        ":VehicleHalVendorClusterTestProperties_JSON",
         ":FakeVehicleHardwareTestOverrideJson",
         ":FakeVehicleHardwareTestPropJson",
     ],
@@ -55,5 +58,5 @@
 
 filegroup {
     name: "FakeVehicleHardwareTestPropJson",
-    srcs: ["prop.json"],
+    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 ab6bf51..c230c51 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>
@@ -80,7 +79,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;
@@ -89,7 +90,9 @@
 class FakeVehicleHardwareTest : public ::testing::Test {
   protected:
     void SetUp() override {
-        mHardware = std::make_unique<FakeVehicleHardware>();
+        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);
@@ -109,6 +112,10 @@
 
     FakeVehicleHardware* getHardware() { return mHardware.get(); }
 
+    void setHardware(std::unique_ptr<FakeVehicleHardware> hardware) {
+        mHardware = std::move(hardware);
+    }
+
     StatusCode setValues(const std::vector<SetValueRequest>& requests) {
         {
             std::scoped_lock<std::mutex> lockGuard(mLock);
@@ -374,7 +381,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) {
@@ -382,7 +390,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.
@@ -394,12 +403,11 @@
             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 (isGlobalProp(propId)) {
             if (config.initialValue == RawPropValues{}) {
                 addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++,
@@ -657,10 +665,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);
@@ -695,10 +705,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);
@@ -711,22 +723,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),
     });
@@ -1840,7 +1846,7 @@
 
 std::string getTestFilePath(const char* filename) {
     static std::string baseDir = android::base::GetExecutableDirectory();
-    return baseDir + "/" + filename;
+    return baseDir + "/fakedata/" + filename;
 }
 
 TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJson) {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/prop.json b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/hardware/test/prop.json
rename to automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
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/grpc/utils/proto_message_converter/Android.bp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
index 7670c25..c368334 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,20 @@
     ],
     vendor: true,
     defaults: ["VehicleHalDefaults"],
-    shared_libs: ["libprotobuf-cpp-full"],
+    shared_libs: [
+        "libprotobuf-cpp-full",
+        "libjsoncpp",
+    ],
     static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties",
         "VehicleHalProtoMessageConverter",
         "VehicleHalProtos",
         "VehicleHalUtils",
         "libgtest",
     ],
+    data: [
+        ":VehicleHalDefaultProperties_JSON",
+    ],
     header_libs: ["VehicleHalDefaultConfig"],
     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/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index 6af1223..08e1990 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -43,6 +43,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>
diff --git a/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h b/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h
index d512713..e6ea6fe 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.
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index 8b4f559..6fec2c9 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -75,10 +75,6 @@
         "VehicleHalDefaults",
         "android-automotive-large-parcelable-defaults",
     ],
-    header_libs: [
-        "IVehicleHardware",
-        "VehicleHalDefaultConfig",
-    ],
     static_libs: [
         "DefaultVehicleHal",
         "FakeVehicleHardware",
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 9c29816..0439ac6 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;
     };
 
@@ -186,8 +186,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;
@@ -263,7 +263,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 138aad5..d447bf8 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -78,14 +78,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,8 +123,8 @@
     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) {
@@ -144,11 +144,10 @@
     }
 
     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 +157,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 +219,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 +231,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 +245,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 +262,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 +276,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);
@@ -349,15 +350,15 @@
 
 ScopedAStatus DefaultVehicleHal::getValues(const CallbackType& callback,
                                            const GetValueRequests& requests) {
+    if (callback == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
     expected<LargeParcelableBase::BorrowedOwnedObject<GetValueRequests>, ScopedAStatus>
             deserializedResults = fromStableLargeParcelable(requests);
     if (!deserializedResults.ok()) {
         ALOGE("getValues: failed to parse getValues requests");
         return std::move(deserializedResults.error());
     }
-    if (callback == nullptr) {
-        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
-    }
     const std::vector<GetValueRequest>& getValueRequests =
             deserializedResults.value().getObject()->payloads;
 
@@ -435,15 +436,15 @@
 
 ScopedAStatus DefaultVehicleHal::setValues(const CallbackType& callback,
                                            const SetValueRequests& requests) {
+    if (callback == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
     expected<LargeParcelableBase::BorrowedOwnedObject<SetValueRequests>, ScopedAStatus>
             deserializedResults = fromStableLargeParcelable(requests);
     if (!deserializedResults.ok()) {
         ALOGE("setValues: failed to parse setValues requests");
         return std::move(deserializedResults.error());
     }
-    if (callback == nullptr) {
-        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
-    }
     const std::vector<SetValueRequest>& setValueRequests =
             deserializedResults.value().getObject()->payloads;
 
@@ -595,18 +596,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";
             }
         }
 
@@ -631,13 +634,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);
     }
-    if (callback == nullptr) {
-        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
-    }
     std::vector<SubscribeOptions> onChangeSubscriptions;
     std::vector<SubscribeOptions> continuousSubscriptions;
     for (const auto& option : options) {
@@ -658,7 +661,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 {
@@ -740,9 +743,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;
@@ -757,18 +760,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() {
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/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index f48b906..36fa5e6 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) {
diff --git a/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
index 3f59363..eb3c663 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
@@ -477,16 +477,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/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
index 154fe65..fc6f157 100644
--- a/automotive/vehicle/tools/generate_annotation_enums.py
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -41,7 +41,7 @@
 TAB = "    "
 RE_ENUM_START = re.compile("\s*enum VehicleProperty \{")
 RE_ENUM_END = re.compile("\s*\}\;")
-RE_COMMENT_BEGIN = 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*")
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/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index b858f50..d5e85b8 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -321,19 +321,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};
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 86f56ae..292d352 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -276,11 +276,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 &&
@@ -288,11 +291,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/boot/aidl/default/BootControl.cpp b/boot/aidl/default/BootControl.cpp
index 4e3c21b..b73c94d 100644
--- a/boot/aidl/default/BootControl.cpp
+++ b/boot/aidl/default/BootControl.cpp
@@ -84,10 +84,12 @@
 
 ScopedAStatus BootControl::getSuffix(int32_t in_slot, std::string* _aidl_return) {
     if (!impl_.IsValidSlot(in_slot)) {
-        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
-                INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
+        // 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);
     }
-    *_aidl_return = impl_.GetSuffix(in_slot);
     return ScopedAStatus::ok();
 }
 
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/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/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 386db52..12b4675 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -112,14 +112,6 @@
             <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>
@@ -128,14 +120,6 @@
             <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>
@@ -161,14 +145,6 @@
             <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="aidl" optional="true">
         <name>android.hardware.boot</name>
         <interface>
@@ -298,21 +274,6 @@
             <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>
@@ -321,17 +282,6 @@
             <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>
@@ -502,14 +452,6 @@
             <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>
@@ -674,14 +616,6 @@
             <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>
@@ -801,6 +735,14 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi</name>
+        <version>1</version>
+        <interface>
+            <name>IWifi</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.wifi</name>
         <version>1.3-6</version>
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/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/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/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 2caa4d5..926d105 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -815,7 +815,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/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
index 57285a3..ae75579 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,7 +118,8 @@
      *    - 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.
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 37371c0..1caf8bc 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -772,6 +772,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 < 33) {
+                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");
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 8f9df24..67e8b21 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -188,6 +188,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);
 
@@ -343,6 +347,11 @@
     string name_;
     string author_;
     long 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 3930074..fa7dccb 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -5772,6 +5772,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;
diff --git a/tv/tuner/aidl/default/Dvr.cpp b/tv/tuner/aidl/default/Dvr.cpp
index c591d07..9928a59 100644
--- a/tv/tuner/aidl/default/Dvr.cpp
+++ b/tv/tuner/aidl/default/Dvr.cpp
@@ -427,7 +427,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/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index 4d48c04..ade265c 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -793,7 +793,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);
@@ -852,11 +853,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 +874,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 +914,10 @@
             }
         }
 
-        uint32_t endPoint = min(184u, 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 +929,8 @@
         }
 
         result = createMediaFilterEventWithIon(mPesOutput);
-        if (result.isOk()) {
+        if (!result.isOk()) {
+            mFilterOutput.clear();
             return result;
         }
     }
@@ -973,7 +1003,8 @@
         if (mSectionSizeLeft == 0) {
             // Location for sectionSize as defined by Section 2.4.4
             // Note that the first 4 bytes skipped are the TsHeader
-            mSectionSizeLeft = ((data[i + 5] & 0x0f) << 8) | (data[i + 6] & 0xff);
+            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);
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..8739668 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -129,8 +129,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 +162,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,
@@ -248,10 +249,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));
@@ -262,7 +262,7 @@
     }
     recordSingleFilterTest(filterConf, frontendConf, dvrConf);
     ASSERT_TRUE(mLnbTests.closeLnb());
-    mLnbId = nullptr;
+    mLnbId = INVALID_LNB_ID;
 }
 
 void TunerRecordAidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterConf,
@@ -494,23 +494,31 @@
     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) {
@@ -839,10 +847,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 +864,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 +876,11 @@
     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(TunerRecordAidlTest, RecordDataFlowWithTsRecordFilterTest) {
@@ -885,9 +907,17 @@
     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(TunerFrontendAidlTest, TuneFrontend) {
@@ -903,7 +933,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 +945,11 @@
     if (!scan.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+    vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
+    for (auto& configuration : scan_configs) {
+        scan = configuration;
+        mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, TuneFrontendWithFrontendSettings) {
@@ -927,7 +965,11 @@
     if (!scan.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+    vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
+    for (auto& configuration : scan_configs) {
+        scan = configuration;
+        mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, LinkToCiCam) {
@@ -1005,8 +1047,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) {
@@ -1022,25 +1072,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 +1108,20 @@
     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]);
+    }
 }
 
 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 e8a7a79..2e69821 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -45,6 +45,8 @@
         ALOGW("[vts] failed to validate connections.");
         return false;
     }
+    determineDataFlows();
+
     return true;
 }
 
@@ -62,6 +64,19 @@
     return success();
 }
 
+void clearIds() {
+    lnbIds.clear();
+    diseqcMsgs.clear();
+    frontendIds.clear();
+    recordDvrIds.clear();
+    descramblerIds.clear();
+    audioFilterIds.clear();
+    videoFilterIds.clear();
+    playbackDvrIds.clear();
+    recordFilterIds.clear();
+    sectionFilterIds.clear();
+}
+
 class TunerLnbAidlTest : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
@@ -77,6 +92,11 @@
         mLnbTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -105,6 +125,11 @@
         mFilterTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -135,6 +160,11 @@
         mFilterTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -201,6 +231,11 @@
         mDvrTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -238,6 +273,11 @@
         mLnbTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -258,7 +298,7 @@
     LnbTests mLnbTests;
 
   private:
-    int32_t* mLnbId = nullptr;
+    int32_t mLnbId = INVALID_LNB_ID;
 };
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerRecordAidlTest);
@@ -278,6 +318,11 @@
         mFrontendTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -308,6 +353,11 @@
         mDvrTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -328,7 +378,7 @@
     void mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf);
 
   private:
-    int32_t* mLnbId = nullptr;
+    int32_t mLnbId = INVALID_LNB_ID;
 };
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerBroadcastAidlTest);
@@ -354,6 +404,11 @@
         mDescramblerTests.setCasService(mCasService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index f093b8e..de12dc0 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -75,6 +75,309 @@
 static LnbRecordHardwareConnections lnbRecord;
 static TimeFilterHardwareConnections timeFilter;
 
+/*
+ * 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 - video filters
+ * index 3 - 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, videoFilterIds,
+                                     sectionFilterIds_optional};
+
+    const int dvrIndex = 0;
+    const int audioFilterIndex = 1;
+    const int videoFilterIndex = 2;
+    const int sectionFilterIndex = 3;
+
+    auto idCombinations = generateIdCombinations(deviceIds);
+    for (auto& combo : idCombinations) {
+        DvrPlaybackHardwareConnections mPlayback;
+        mPlayback.dvrId = combo[dvrIndex];
+        mPlayback.audioFilterId = combo[audioFilterIndex];
+        mPlayback.videoFilterId = combo[videoFilterIndex];
+        mPlayback.sectionFilterId = combo[sectionFilterIndex];
+        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 - video filters
+ * index 3 - lnbs
+ */
+static inline vector<LnbLiveHardwareConnections> generateLnbLiveCombinations() {
+    vector<LnbLiveHardwareConnections> combinations;
+    vector<vector<string>> deviceIds{frontendIds, audioFilterIds, videoFilterIds, lnbIds};
+
+    const int frontendIndex = 0;
+    const int audioFilterIndex = 1;
+    const int videoFilterIndex = 2;
+    const int lnbIndex = 3;
+
+    // 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];
+            mLnbLive.videoFilterId = combo[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 - video filters
+ * index 4 - Dvr SW Fe Connections
+ * index 5 - 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 videoFilterIndex = 3;
+    const int dvrFeIdIndex = 4;
+    const int dvrSourceIdIndex = 5;
+
+    vector<vector<string>> deviceIds{descramblerIds, mfrontendIds,        audioFilterIds,
+                                     videoFilterIds, 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];
+        mDescrambling.videoFilterId = combo[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;
+}
+
 /** Config all the frontends that would be used in the tests */
 inline void initFrontendConfig() {
     // The test will use the internal default fe when default fe is connected to any data flow
@@ -182,6 +485,87 @@
     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 (hasSwFe && !hasHwFe && dvrMap.empty()) {
+        ALOGD("Cannot configure Live. Only software frontends and no dvr connections");
+        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;
+}
+
 /** Read the vendor configurations of which hardware to use for each test cases/data flows */
 inline void connectHardwaresToTestCases() {
     TunerTestingConfigAidlReader1_0::connectLiveBroadcast(live);
@@ -194,6 +578,17 @@
     TunerTestingConfigAidlReader1_0::connectDvrPlayback(playback);
 };
 
+inline void determineDataFlows() {
+    determineScan();
+    determineTimeFilter();
+    determineDvrPlayback();
+    determineLnbLive();
+    determineLnbRecord();
+    determineLive();
+    determineDescrambling();
+    determineDvrRecord();
+}
+
 inline bool validateConnections() {
     if (record.support && !record.hasFrontendConnection &&
         record.dvrSourceId.compare(emptyHardwareId) == 0) {
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index b6e1020..6fafd59 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -62,10 +62,33 @@
 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;
+
 const string emptyHardwareId = "";
 
 static string mConfigFilePath;
 
+static vector<string> playbackDvrIds;
+static vector<string> recordDvrIds;
+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,                                 " \
@@ -137,6 +160,7 @@
     string ipFilterId;
     string pcrFilterId;
     /* list string of extra filters; */
+    vector<string> extraFilters;
 };
 
 struct ScanHardwareConnections {
@@ -249,6 +273,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"));
@@ -310,6 +335,11 @@
                 }
                 frontendMap[id].type = type;
                 frontendMap[id].isSoftwareFe = feConfig.getIsSoftwareFrontend();
+                if (frontendMap[id].isSoftwareFe) {
+                    hasSwFe = true;
+                } else {
+                    hasHwFe = true;
+                }
                 // TODO: b/182519645 complete the tune status config
                 frontendMap[id].tuneStatusTypes = types;
                 frontendMap[id].expectTuneStatuses = statuses;
@@ -384,11 +414,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));
@@ -412,6 +444,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 {
@@ -430,6 +463,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()) {
@@ -455,6 +489,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);
                 }
@@ -477,6 +512,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasClearLiveBroadcast()) {
             live.hasFrontendConnection = true;
+            configuredLive = true;
         } else {
             live.hasFrontendConnection = false;
             return;
@@ -504,12 +540,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;
@@ -522,6 +563,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasDvrPlayback()) {
             playback.support = true;
+            configuredPlayback = true;
         } else {
             playback.support = false;
             return;
@@ -535,12 +577,9 @@
         } else {
             playback.sectionFilterId = emptyHardwareId;
         }
-        if (playbackConfig.hasOptionalFilters() && !playback.hasExtraFilters) {
-            auto optionalFilters = playbackConfig.getFirstOptionalFilters()->getOptionalFilter();
-            for (size_t i = 0; i < optionalFilters.size(); ++i) {
-                playback.extraFilters.push_back(optionalFilters[i].getFilterId());
-            }
-            playback.hasExtraFilters = true;
+        if (playbackConfig.hasOptionalFilters()) {
+            auto optionalFilters = playbackConfig.getOptionalFilters();
+            playback.extraFilters = optionalFilters;
         }
     }
 
@@ -548,6 +587,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasDvrRecord()) {
             record.support = true;
+            configuredRecord = true;
         } else {
             record.support = false;
             return;
@@ -572,6 +612,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasDescrambling()) {
             descrambling.support = true;
+            configuredDescrambling = true;
         } else {
             descrambling.support = false;
             return;
@@ -601,6 +642,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasLnbLive()) {
             lnbLive.support = true;
+            configuredLnbLive = true;
         } else {
             lnbLive.support = false;
             return;
@@ -625,6 +667,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasLnbRecord()) {
             lnbRecord.support = true;
+            configuredLnbRecord = true;
         } else {
             lnbRecord.support = false;
             return;
@@ -649,6 +692,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasTimeFilter()) {
             timeFilter.support = true;
+            configuredTimeFilter = true;
         } else {
             timeFilter.support = false;
             return;
@@ -704,17 +748,17 @@
             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;
     }
 
@@ -799,6 +843,16 @@
         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());
+        }
+
         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 9b500c3..79efb1b 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -47,6 +47,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();
@@ -54,6 +55,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);
@@ -83,21 +85,16 @@
     ctor public DataFlowConfiguration.DvrPlayback();
     method @Nullable public String getAudioFilterConnection();
     method @Nullable public String getDvrConnection();
-    method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback.OptionalFilters getOptionalFilters();
+    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 android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback.OptionalFilters);
+    method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
     method public void setSectionFilterConnection(@Nullable String);
     method public void setVideoFilterConnection(@Nullable String);
   }
 
-  public static class DataFlowConfiguration.DvrPlayback.OptionalFilters {
-    ctor public DataFlowConfiguration.DvrPlayback.OptionalFilters();
-    method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.OptionalFilter> getOptionalFilter();
-  }
-
   public static class DataFlowConfiguration.DvrRecord {
     ctor public DataFlowConfiguration.DvrRecord();
     method @Nullable public String getDvrRecordConnection();
@@ -181,13 +178,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 {
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 90f3c9b..1a148a4 100644
--- a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
+++ b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
@@ -68,7 +68,8 @@
             <frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
                       connectToCicamId="0" removeOutputPid="10" frequency="578000000"
                       endFrequency="800000000">
-              <dvbsFrontendSettings inputStreamId="0" symbolRate="0"/>
+              <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"
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index ee768ba..e0f2579 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -77,8 +77,14 @@
     <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"/>
@@ -644,7 +650,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>
@@ -665,7 +671,6 @@
                     <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"/>
@@ -679,14 +684,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"/>
-                    <xs:element name="optionalFilters" minOccurs="0" maxOccurs="1">
-                      <xs:complexType>
-                          <xs:sequence>
-                            <xs:element name="optionalFilter" type="optionalFilter" minOccurs="1" maxOccurs="unbounded"/>
-                          </xs:sequence>
-                      </xs:complexType>
-                    </xs:element>
-                    <!--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">
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/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 cd08671..39bb5d9 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
@@ -47,4 +47,5 @@
   SUPPORTED_MIN_RANGING_INTERVAL_MS = 228,
   SUPPORTED_RANGE_DATA_NTF_CONFIG = 229,
   SUPPORTED_RSSI_REPORTING = 230,
+  SUPPORTED_DIAGNOSTICS = 231,
 }
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/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index d35728f..8413f06 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
@@ -43,4 +43,6 @@
   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/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index 556bd13..86479fb 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -171,4 +171,12 @@
      * 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,
 }
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
index e389a2d..42d52f1 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -31,4 +31,8 @@
     // Used to set the current regulatory country code (determined usinag
     // SIM or hardcoded by OEM).
     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/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index f43b249..f303ed9 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -66,4 +66,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/wifi/aidl/Android.bp b/wifi/aidl/Android.bp
new file mode 100644
index 0000000..c0ca667
--- /dev/null
+++ b/wifi/aidl/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"],
+}
+
+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: {
+                enabled: false,
+            },
+        },
+    },
+}
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..a102b97
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.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
+interface IWifiApIface {
+  String getName();
+  String[] getBridgedInstances();
+  byte[6] getFactoryMacAddress();
+  void setCountryCode(in byte[2] code);
+  int[] getValidFrequenciesForBand(in android.hardware.wifi.WifiBand band);
+  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..647891f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, 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();
+  android.hardware.wifi.IWifiChip.ChipCapabilityMask getCapabilities();
+  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.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
+  android.hardware.wifi.WifiUsableChannel[] getUsableChannels(in android.hardware.wifi.WifiBand band, in android.hardware.wifi.WifiIfaceMode ifaceModeMask, in android.hardware.wifi.IWifiChip.UsableChannelFilter filterMask);
+  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 android.hardware.wifi.IWifiChip.CoexRestriction 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();
+  const int NO_POWER_CAP_CONSTANT = 2147483647;
+  @Backing(type="int") @VintfStability
+  enum ChipCapabilityMask {
+    DEBUG_MEMORY_FIRMWARE_DUMP = 1,
+    DEBUG_MEMORY_DRIVER_DUMP = 2,
+    DEBUG_RING_BUFFER_CONNECT_EVENT = 4,
+    DEBUG_RING_BUFFER_POWER_EVENT = 8,
+    DEBUG_RING_BUFFER_WAKELOCK_EVENT = 16,
+    DEBUG_RING_BUFFER_VENDOR_DATA = 32,
+    DEBUG_HOST_WAKE_REASON_STATS = 64,
+    DEBUG_ERROR_ALERTS = 128,
+    SET_TX_POWER_LIMIT = 256,
+    D2D_RTT = 512,
+    D2AP_RTT = 1024,
+    USE_BODY_HEAD_SAR = 2048,
+    SET_LATENCY_MODE = 4096,
+    P2P_RAND_MAC = 8192,
+    WIGIG = 16384,
+  }
+  @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,
+    SOFTAP = 2,
+    WIFI_AWARE = 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,
+    CONCURRENCY = 2,
+    NAN_INSTANT_MODE = 4,
+  }
+}
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..070ca24
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.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 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 transmitFollowupRequest(in char cmdId, in android.hardware.wifi.NanTransmitFollowupRequest msg);
+  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..591cd8c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, 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 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 notifyTransmitFollowupResponse(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..2f0dfa1
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, 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();
+  android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask getCapabilities();
+  android.hardware.wifi.WifiDebugRxPacketFateReport[] getDebugRxPacketFates();
+  android.hardware.wifi.WifiDebugTxPacketFateReport[] getDebugTxPacketFates();
+  byte[6] getFactoryMacAddress();
+  android.hardware.wifi.StaLinkLayerStats getLinkLayerStats();
+  android.hardware.wifi.StaRoamingCapabilities getRoamingCapabilities();
+  int[] getValidFrequenciesForBand(in android.hardware.wifi.WifiBand band);
+  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);
+  @Backing(type="int") @VintfStability
+  enum StaIfaceCapabilityMask {
+    APF = 1,
+    BACKGROUND_SCAN = 2,
+    LINK_LAYER_STATS = 4,
+    RSSI_MONITOR = 8,
+    CONTROL_ROAMING = 16,
+    PROBE_IE_ALLOWLIST = 32,
+    SCAN_RAND = 64,
+    STA_5G = 128,
+    HOTSPOT = 256,
+    PNO = 512,
+    TDLS = 1024,
+    TDLS_OFFCHANNEL = 2048,
+    ND_OFFLOAD = 4096,
+    KEEP_ALIVE = 8192,
+    DEBUG_PACKET_FATE = 16384,
+  }
+}
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..0a3ad1a
--- /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 = 0,
+  AP = 1,
+  AP_BRIDGED = 2,
+  P2P = 3,
+  NAN_IFACE = 4,
+}
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..dbdc439
--- /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 = 0,
+  AP = 1,
+  P2P = 2,
+  NAN_IFACE = 3,
+}
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..ca6c910
--- /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 = 1,
+  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/NanCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
new file mode 100644
index 0000000..c44654e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.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.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;
+  android.hardware.wifi.NanCipherSuiteType supportedCipherSuites;
+  boolean instantCommunicationModeSupportFlag;
+}
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..4450956
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.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 NanCipherSuiteType {
+  NONE = 0,
+  SHARED_KEY_128_MASK = 1,
+  SHARED_KEY_256_MASK = 2,
+  PUBLIC_KEY_128_MASK = 4,
+  PUBLIC_KEY_256_MASK = 8,
+}
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..1dfa45f
--- /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 = 1,
+  JOINED_CLUSTER = 2,
+}
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..682699e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.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 NanConfigRequestSupplemental {
+  int discoveryBeaconIntervalMs;
+  int numberOfSpatialStreamsInDiscovery;
+  boolean enableDiscoveryWindowEarlyTermination;
+  boolean enableRanging;
+  boolean enableInstantCommunicationMode;
+  int instantModeChannel;
+}
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..ce75288
--- /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 = 1,
+  FORCE_CHANNEL_SETUP = 2,
+}
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..64288ca
--- /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 = 0,
+  PMK = 1,
+  PASSPHRASE = 2,
+}
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..761cdbb
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.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 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;
+  android.hardware.wifi.NanRangingIndication configRangingIndications;
+  char distanceIngressCm;
+  char distanceEgressCm;
+}
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/NanInitiateDataPathRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl
new file mode 100644
index 0000000..697e29a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.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 NanInitiateDataPathRequest {
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  android.hardware.wifi.NanDataPathChannelCfg channelRequestType;
+  int channel;
+  String ifaceName;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  byte[] appInfo;
+  byte[] serviceNameOutOfBand;
+}
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..dab33ad
--- /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 = 1,
+  MATCH_NEVER = 2,
+}
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..ae430c4
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.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.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;
+  android.hardware.wifi.NanRangingIndication rangingIndicationType;
+  byte[] scid;
+}
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..d8d6b1b
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.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 NanPublishRequest {
+  android.hardware.wifi.NanDiscoveryCommonConfig baseConfigs;
+  android.hardware.wifi.NanPublishType publishType;
+  android.hardware.wifi.NanTxType txType;
+  boolean autoAcceptDataPathRequests;
+}
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..fc9b7a0
--- /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 = 1,
+  UNSOLICITED_SOLICITED = 2,
+}
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..d03dffc
--- /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,
+  INGRESS_MET_MASK = 2,
+  EGRESS_MET_MASK = 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..5542ff6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.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 NanRespondToDataPathIndicationRequest {
+  boolean acceptRequest;
+  int ndpInstanceId;
+  String ifaceName;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  byte[] appInfo;
+  byte[] serviceNameOutOfBand;
+}
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..3c0583c
--- /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 = 1,
+}
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..9eaf518
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.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;
+@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,
+}
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..bf176a5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.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 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;
+}
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..325e40b
--- /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 = 1,
+}
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..6f7696f
--- /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 = 1,
+}
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..bd7efff
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.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 RttBw {
+  BW_5MHZ = 1,
+  BW_10MHZ = 2,
+  BW_20MHZ = 4,
+  BW_40MHZ = 8,
+  BW_80MHZ = 16,
+  BW_160MHZ = 32,
+  BW_320MHZ = 64,
+}
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..02e6479
--- /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 = 1,
+  HT = 2,
+  VHT = 4,
+  HE = 8,
+  EHT = 16,
+}
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..743e0bd
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.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.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;
+}
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..1041dd7
--- /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,
+  FULL_RESULTS = 2,
+  NO_BATCH = 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..b49d406
--- /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;
+  android.hardware.wifi.StaBackgroundScanBucketEventReportSchemeMask 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..cf68fc6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.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 StaLinkLayerIfaceStats {
+  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;
+}
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..5903760
--- /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 {
+  android.hardware.wifi.StaScanDataFlagMask 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..dc8f2f1
--- /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,
+}
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..8c45044
--- /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,
+  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/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..ee26f2e
--- /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 = 0,
+  ETHERNET_II = 1,
+  MGMT_80211 = 2,
+}
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..f210e82
--- /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,
+  HAS_ASCII_ENTRIES = 2,
+  HAS_PER_PACKET_ENTRIES = 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..75abb4e
--- /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 = 0,
+  FW_QUEUED = 1,
+  FW_DROP_FILTER = 2,
+  FW_DROP_INVALID = 3,
+  FW_DROP_NOBUFS = 4,
+  FW_DROP_OTHER = 5,
+  DRV_QUEUED = 6,
+  DRV_DROP_FILTER = 7,
+  DRV_DROP_INVALID = 8,
+  DRV_DROP_NOBUFS = 9,
+  DRV_DROP_OTHER = 10,
+}
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..e360c2c
--- /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 = 0,
+  SENT = 1,
+  FW_QUEUED = 2,
+  FW_DROP_INVALID = 3,
+  FW_DROP_NOBUFS = 4,
+  FW_DROP_OTHER = 5,
+  DRV_QUEUED = 6,
+  DRV_DROP_INVALID = 7,
+  DRV_DROP_NOBUFS = 8,
+  DRV_DROP_OTHER = 9,
+}
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..e2fe57a
--- /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,
+  IFACE_MODE_SOFTAP = 2,
+  IFACE_MODE_IBSS = 4,
+  IFACE_MODE_P2P_CLIENT = 8,
+  IFACE_MODE_P2P_GO = 16,
+  IFACE_MODE_NAN = 32,
+  IFACE_MODE_MESH = 64,
+  IFACE_MODE_TDLS = 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/WifiRadioCombinationMatrix.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
new file mode 100644
index 0000000..ea86c4f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombinationMatrix.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 WifiRadioCombinationMatrix {
+  android.hardware.wifi.WifiRadioCombination[] radioCombinations;
+}
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..f27661c
--- /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 = 0,
+  ERROR_WIFI_CHIP_INVALID = 1,
+  ERROR_WIFI_IFACE_INVALID = 2,
+  ERROR_WIFI_RTT_CONTROLLER_INVALID = 3,
+  ERROR_NOT_SUPPORTED = 4,
+  ERROR_NOT_AVAILABLE = 5,
+  ERROR_NOT_STARTED = 6,
+  ERROR_INVALID_ARGS = 7,
+  ERROR_BUSY = 8,
+  ERROR_UNKNOWN = 9,
+}
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..94e3a8a
--- /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;
+  android.hardware.wifi.WifiIfaceMode ifaceModeMask;
+}
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..71ea385
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
@@ -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.
+ */
+
+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);
+
+    /**
+     * Used to query the list of valid frequencies (depending on country code set)
+     * for the provided band.
+     *
+     * @param band Band for which the frequency list is being generated.
+     * @return Vector of valid frequencies for the provided band.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    int[] getValidFrequenciesForBand(in WifiBand band);
+
+    /**
+     * 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..fe9a6f3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -0,0 +1,1096 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.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.WifiDebugHostWakeReasonStats;
+import android.hardware.wifi.WifiDebugRingBufferStatus;
+import android.hardware.wifi.WifiDebugRingBufferVerboseLevel;
+import android.hardware.wifi.WifiIfaceMode;
+import android.hardware.wifi.WifiRadioCombinationMatrix;
+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 ChipCapabilityMask {
+        /**
+         * Memory dump of Firmware.
+         */
+        DEBUG_MEMORY_FIRMWARE_DUMP = 1 << 0,
+        /**
+         * Memory dump of Driver.
+         */
+        DEBUG_MEMORY_DRIVER_DUMP = 1 << 1,
+        /**
+         * Connectivity events reported via debug ring buffer.
+         */
+        DEBUG_RING_BUFFER_CONNECT_EVENT = 1 << 2,
+        /**
+         * Power events reported via debug ring buffer.
+         */
+        DEBUG_RING_BUFFER_POWER_EVENT = 1 << 3,
+        /**
+         * Wakelock events reported via debug ring buffer.
+         */
+        DEBUG_RING_BUFFER_WAKELOCK_EVENT = 1 << 4,
+        /**
+         * Vendor data reported via debug ring buffer.
+         * This mostly contains firmware event logs.
+         */
+        DEBUG_RING_BUFFER_VENDOR_DATA = 1 << 5,
+        /**
+         * Host wake reasons stats collection.
+         */
+        DEBUG_HOST_WAKE_REASON_STATS = 1 << 6,
+        /**
+         * Error alerts.
+         */
+        DEBUG_ERROR_ALERTS = 1 << 7,
+        /**
+         * Set/Reset Tx Power limits.
+         */
+        SET_TX_POWER_LIMIT = 1 << 8,
+        /**
+         * Device to Device RTT.
+         */
+        D2D_RTT = 1 << 9,
+        /**
+         * Device to AP RTT.
+         */
+        D2AP_RTT = 1 << 10,
+        /**
+         * Set/Reset Tx Power limits.
+         */
+        USE_BODY_HEAD_SAR = 1 << 11,
+        /**
+         * Set Latency Mode.
+         */
+        SET_LATENCY_MODE = 1 << 12,
+        /**
+         * Support P2P MAC randomization.
+         */
+        P2P_RAND_MAC = 1 << 13,
+        /**
+         * Chip can operate in the 60GHz band (WiGig chip).
+         */
+        WIGIG = 1 << 14,
+    }
+
+    /**
+     * 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.
+     * Must fail if |ChipCapabilityMask.DEBUG_ERROR_ALERTS| is not set.
+     *
+     * @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 capabilities supported by this chip.
+     *
+     * @return Bitset of |ChipCapabilityMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    ChipCapabilityMask getCapabilities();
+
+    /**
+     * 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 represented by
+     *         |WifiRadioCombinationMatrix|.
+     *         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|
+     *
+     */
+    WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
+
+    /**
+     * 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 WifiIfaceMode ifaceModeMask, in UsableChannelFilter filterMask);
+
+    /**
+     * 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 CoexRestriction 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();
+}
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..45644b4
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl
@@ -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.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.IWifiNanIfaceEventCallback;
+import android.hardware.wifi.NanConfigRequest;
+import android.hardware.wifi.NanConfigRequestSupplemental;
+import android.hardware.wifi.NanEnableRequest;
+import android.hardware.wifi.NanInitiateDataPathRequest;
+import android.hardware.wifi.NanPublishRequest;
+import android.hardware.wifi.NanRespondToDataPathIndicationRequest;
+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.
+     * @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.
+     * @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);
+
+    /**
+     * 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);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
new file mode 100644
index 0000000..470b7ba
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.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.NanStatus;
+
+/**
+ * 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 cmdId 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 invoked in response to a capability request
+     * |IWifiNanIface.getCapabilitiesRequest|.
+     *
+     * @param cmdId 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 cmdId 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 cmdId 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 cmdId 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 cmdId 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 cmdId 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 cmdId 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 cmdId 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 cmdId 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 cmdId 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 cmdId 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 cmdId 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 cmdId 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 transmit followup request
+     * |IWifiNanIface.transmitFollowupRequest|.
+     *
+     * @param cmdId 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);
+}
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..2dd57b2
--- /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 StaIfaceCapabilityMask {
+        /**
+         * 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,
+        /**
+         * Support for tracking connection packets' fate.
+         */
+        DEBUG_PACKET_FATE = 1 << 14,
+    }
+
+    /**
+     * 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 capabilities supported by this STA iface.
+     *
+     * @return Bitset of |StaIfaceCapabilityMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaIfaceCapabilityMask getCapabilities();
+
+    /**
+     * 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();
+
+    /**
+     * Used to query the list of valid frequencies (depending on the country
+     * code set) for the provided band. These channels may be specified in the
+     * |BackgroundScanBucketParameters.frequenciesInMhz| for a background scan
+     * request.
+     *
+     * @param band Band for which the frequency list is being generated.
+     * @return Vector of valid frequencies for the provided band.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    int[] getValidFrequenciesForBand(in WifiBand band);
+
+    /**
+     * 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);
+}
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..d59dfe3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/MacAddress.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;
+
+/**
+ * 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.
+ *
+ * TODO (b/210705533): Replace this type with a 2D byte array.
+ */
+@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/NanCapabilities.aidl b/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
new file mode 100644
index 0000000..6042a05
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanCapabilities.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.NanCipherSuiteType;
+
+/**
+ * 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;
+    /**
+     * The set of supported Cipher suites. The |NanCipherSuiteType| bit fields are used.
+     */
+    NanCipherSuiteType supportedCipherSuites;
+    /**
+     * Flag to indicate id instant communication mode is supported.
+     */
+    boolean instantCommunicationModeSupportFlag;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl b/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl
new file mode 100644
index 0000000..9e3d684
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.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;
+
+/**
+ * Cipher suite flags.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanCipherSuiteType {
+    NONE = 0,
+    SHARED_KEY_128_MASK = 1 << 0,
+    SHARED_KEY_256_MASK = 1 << 1,
+    /**
+     *  NCS-PK-128
+     */
+    PUBLIC_KEY_128_MASK = 1 << 2,
+    /**
+     *  NCS-PK-256
+     */
+    PUBLIC_KEY_256_MASK = 1 << 3,
+}
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..eb01a9f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.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.
+ */
+
+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;
+}
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..42a5616
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.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;
+
+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;
+    /**
+     * Cipher type for data-paths. If |securityType| is |NanDataPathSecurityType.OPEN| then 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..ca1e016
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.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.NanDataPathSecurityConfig;
+import android.hardware.wifi.NanMatchAlg;
+import android.hardware.wifi.NanRangingIndication;
+
+/**
+ * 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;
+    /**
+     * The type of ranging feedback to be provided by discovery session matches
+     * |IWifiNanIfaceEventCallback.eventMatch|. Only relevant if |rangingRequired| is true.
+     */
+    NanRangingIndication 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;
+}
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/NanInitiateDataPathRequest.aidl b/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl
new file mode 100644
index 0000000..264a873
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.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.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;
+}
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..896cde0
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.NanRangingIndication;
+
+/**
+ * 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;
+    /**
+     * 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;
+    /**
+     * The ranging event(s) which triggered the ranging. e.g. can indicate that continuous ranging
+     * was requested, or else that an ingress event occurred.
+     */
+    NanRangingIndication rangingIndicationType;
+    /**
+     * Security Context Identifier attribute contains PMKID. Shall be included in NDP setup and
+     * response messages. Security Context Identifie 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;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
new file mode 100644
index 0000000..6dd079c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPublishRequest.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.NanDiscoveryCommonConfig;
+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;
+}
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..6960e71
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.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.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;
+}
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..d63a50e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanStatusCode.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.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,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
new file mode 100644
index 0000000..12c1170
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.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.MacAddress;
+import android.hardware.wifi.NanDiscoveryCommonConfig;
+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;
+}
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/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/RttBw.aidl b/wifi/aidl/android/hardware/wifi/RttBw.aidl
new file mode 100644
index 0000000..9d42dc0
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttBw.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;
+
+/**
+ * RTT Measurement Bandwidth.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttBw {
+    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..565cce7
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.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;
+}
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..fd985a3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/Ssid.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;
+
+/**
+ * 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.
+ *
+ * TODO (b/210705533): Replace this type with a 2D byte array.
+ */
+@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..7bd87b2
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
@@ -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.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.StaBackgroundScanBucketEventReportSchemeMask;
+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.
+     */
+    StaBackgroundScanBucketEventReportSchemeMask 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..78f8caa
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.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.StaLinkLayerIfaceContentionTimeStats;
+import android.hardware.wifi.StaLinkLayerIfacePacketStats;
+import android.hardware.wifi.StaPeerInfo;
+
+/**
+ * Iface statistics for the current connection.
+ */
+@VintfStability
+parcelable StaLinkLayerIfaceStats {
+    /**
+     * Number beacons received from the connected AP.
+     */
+    int beaconRx;
+    /**
+     * Access Point Beacon and Management frames RSSI (averaged).
+     */
+    int avgRssiMgmt;
+    /**
+     * WME Best Effort Access Category packet counters.
+     */
+    StaLinkLayerIfacePacketStats wmeBePktStats;
+    /**
+     * WME Background Access Category packet counters.
+     */
+    StaLinkLayerIfacePacketStats wmeBkPktStats;
+    /**
+     * WME Video Access Category packet counters.
+     */
+    StaLinkLayerIfacePacketStats wmeViPktStats;
+    /**
+     * WME Voice Access Category packet counters.
+     */
+    StaLinkLayerIfacePacketStats wmeVoPktStats;
+    /**
+     * Duty cycle for the iface.
+     * If this iface is being served using time slicing on a radio with one or more ifaces
+     * (i.e MCC), then the duty cycle assigned to this iface in %.
+     * If not using time slicing (i.e SCC or DBS), set to 100.
+     */
+    byte timeSliceDutyCycleInPercent;
+    /**
+     * WME Best Effort (BE) Access Category (AC) contention time statistics.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+    /**
+     * WME Background (BK) Access Category (AC) contention time statistics.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+    /**
+     * WME Video (VI) Access Category (AC) contention time statistics.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+    /**
+     * WME Voice (VO) Access Category (AC) contention time statistics.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+    /**
+     * Per peer statistics.
+     */
+    StaPeerInfo[] peers;
+}
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..9d6bd53
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaScanData.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.StaScanDataFlagMask;
+import android.hardware.wifi.StaScanResult;
+
+/**
+ * Structure describing all of the access points seen during
+ * the scan.
+ */
+@VintfStability
+parcelable StaScanData {
+    /**
+     * Bitset containing |ScanDataFlagMask| values.
+     */
+    StaScanDataFlagMask 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/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/WifiRadioCombinationMatrix.aidl b/wifi/aidl/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
new file mode 100644
index 0000000..b79a818
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRadioCombinationMatrix.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;
+
+import android.hardware.wifi.WifiRadioCombination;
+
+/**
+ * Wifi radio combinations matrix retrieved via
+ * |IWifiChip.getSupportedRadioCombinationsMatrix|.
+ */
+@VintfStability
+parcelable WifiRadioCombinationMatrix {
+    /**
+     * List of all the possible radio combinations that the chip can operate.
+     */
+    WifiRadioCombination[] radioCombinations;
+}
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..d92e4cc
--- /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;
+import android.hardware.wifi.WifiIfaceMode;
+
+/**
+ * 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.
+     */
+    WifiIfaceMode ifaceModeMask;
+}
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 d95bd03..b7984fa 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>
@@ -38,6 +39,7 @@
 using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
 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;
@@ -413,7 +415,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