Merge changes I36d1e494,I65a74ac6 into main

* changes:
  Add missing supportedEnumValues
  Add missing status codes
diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS
index 15de48f..4787f0b 100644
--- a/automotive/evs/OWNERS
+++ b/automotive/evs/OWNERS
@@ -1,2 +1,2 @@
 ankitarora@google.com
-jwhpryor@google.com
+changyeon@google.com
diff --git a/automotive/evs/aidl/impl/default/Android.bp b/automotive/evs/aidl/impl/default/Android.bp
index 70c523b..79ee956 100644
--- a/automotive/evs/aidl/impl/default/Android.bp
+++ b/automotive/evs/aidl/impl/default/Android.bp
@@ -60,12 +60,15 @@
         "libyuv",
     ],
     static_libs: [
-        "android.frameworks.automotive.display-V1-ndk",
+        "android.frameworks.automotive.display-V2-ndk",
         "android.hardware.automotive.evs-V2-ndk",
         "android.hardware.common-V2-ndk",
         "libaidlcommonsupport",
         "libcutils",
     ],
+    header_libs: [
+        "libgui_aidl_headers",
+    ],
     local_include_dirs: ["include"],
     include_dirs: ["frameworks/native/include/"],
     required: ["evs_mock_hal_configuration.xml"],
diff --git a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
index 259c266..3897b4e 100644
--- a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
+++ b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
@@ -27,6 +27,7 @@
 #include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
 #include <aidl/android/hardware/automotive/evs/IEvsEnumeratorStatusCallback.h>
 #include <aidl/android/hardware/automotive/evs/Stream.h>
+#include <android-base/thread_annotations.h>
 #include <utils/Thread.h>
 
 #include <atomic>
diff --git a/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h b/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h
index ceabd9e..0865a04 100644
--- a/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h
+++ b/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h
@@ -23,6 +23,7 @@
 #include <aidl/android/hardware/automotive/evs/BufferDesc.h>
 #include <aidl/android/hardware/automotive/evs/DisplayDesc.h>
 #include <aidl/android/hardware/automotive/evs/DisplayState.h>
+#include <android-base/thread_annotations.h>
 
 #include <thread>
 
diff --git a/automotive/evs/aidl/impl/default/include/GlWrapper.h b/automotive/evs/aidl/impl/default/include/GlWrapper.h
index adb250c..7ff6104 100644
--- a/automotive/evs/aidl/impl/default/include/GlWrapper.h
+++ b/automotive/evs/aidl/impl/default/include/GlWrapper.h
@@ -25,7 +25,7 @@
 #include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
 #include <aidl/android/hardware/automotive/evs/BufferDesc.h>
 #include <android-base/logging.h>
-#include <bufferqueueconverter/BufferQueueConverter.h>
+#include <cutils/native_handle.h>
 
 namespace aidl::android::hardware::automotive::evs::implementation {
 
@@ -33,7 +33,6 @@
 
 class GlWrapper {
   public:
-    GlWrapper() : mSurfaceHolder(::android::SurfaceHolderUniquePtr(nullptr, nullptr)) {}
     bool initialize(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
                     uint64_t displayId);
     void shutdown();
@@ -53,9 +52,6 @@
     unsigned getHeight() { return mHeight; };
 
   private:
-    ::android::sp<::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer>
-            mGfxBufferProducer;
-
     EGLDisplay mDisplay;
     EGLSurface mSurface;
     EGLContext mContext;
@@ -71,9 +67,6 @@
     // Opaque handle for a native hardware buffer defined in
     // frameworks/native/opengl/include/EGL/eglplatform.h
     ANativeWindow* mWindow;
-
-    // Pointer to a Surface wrapper.
-    ::android::SurfaceHolderUniquePtr mSurfaceHolder;
 };
 
 }  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
index e5f8e4c..5b5cbcc 100644
--- a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
@@ -352,8 +352,8 @@
     BufferDesc bufferDescToSend = {
             .buffer =
                     {
-                            .handle = std::move(::android::dupToAidl(mBuffer.handle)),
                             .description = mBuffer.description,
+                            .handle = std::move(::android::dupToAidl(mBuffer.handle)),
                     },
             .pixelSizeBytes = 4,  // RGBA_8888 is 4-byte-per-pixel format
             .bufferId = mBuffer.fingerprint,
diff --git a/automotive/evs/aidl/impl/default/src/GlWrapper.cpp b/automotive/evs/aidl/impl/default/src/GlWrapper.cpp
index 0ee5ecb..a9d0213 100644
--- a/automotive/evs/aidl/impl/default/src/GlWrapper.cpp
+++ b/automotive/evs/aidl/impl/default/src/GlWrapper.cpp
@@ -19,6 +19,7 @@
 #include <aidl/android/frameworks/automotive/display/DisplayDesc.h>
 #include <aidl/android/hardware/graphics/common/HardwareBufferDescription.h>
 #include <aidlcommonsupport/NativeHandle.h>
+#include <gui/view/Surface.h>
 #include <ui/DisplayMode.h>
 #include <ui/DisplayState.h>
 #include <ui/GraphicBuffer.h>
@@ -183,20 +184,6 @@
     return program;
 }
 
-::android::sp<HGraphicBufferProducer> convertNativeHandleToHGBP(const NativeHandle& aidlHandle) {
-    native_handle_t* handle = ::android::dupFromAidl(aidlHandle);
-    if (handle->numFds != 0 || handle->numInts < std::ceil(sizeof(size_t) / sizeof(int))) {
-        LOG(ERROR) << "Invalid native handle";
-        return nullptr;
-    }
-    ::android::hardware::hidl_vec<uint8_t> halToken;
-    halToken.setToExternal(reinterpret_cast<uint8_t*>(const_cast<int*>(&(handle->data[1]))),
-                           handle->data[0]);
-    ::android::sp<HGraphicBufferProducer> hgbp =
-            HGraphicBufferProducer::castFrom(::android::retrieveHalInterface(halToken));
-    return std::move(hgbp);
-}
-
 }  // namespace
 
 namespace aidl::android::hardware::automotive::evs::implementation {
@@ -226,30 +213,19 @@
     }
     LOG(INFO) << "Display resolution is " << mWidth << "x" << mHeight;
 
-    NativeHandle aidlHandle;
-    status = pWindowProxy->getHGraphicBufferProducer(displayId, &aidlHandle);
+    aidl::android::view::Surface shimSurface;
+    status = pWindowProxy->getSurface(displayId, &shimSurface);
     if (!status.isOk()) {
-        LOG(ERROR) << "Failed to get IGraphicBufferProducer from ICarDisplayProxy.";
+        LOG(ERROR) << "Failed to obtain the surface.";
         return false;
     }
 
-    mGfxBufferProducer = convertNativeHandleToHGBP(aidlHandle);
-    if (!mGfxBufferProducer) {
-        LOG(ERROR) << "Failed to convert a NativeHandle to HGBP.";
-        return false;
-    }
-
-    mSurfaceHolder = getSurfaceFromHGBP(mGfxBufferProducer);
-    if (mSurfaceHolder == nullptr) {
-        LOG(ERROR) << "Failed to get a Surface from HGBP.";
-        return false;
-    }
-
-    mWindow = getNativeWindow(mSurfaceHolder.get());
+    mWindow = shimSurface.get();
     if (mWindow == nullptr) {
         LOG(ERROR) << "Failed to get a native window from Surface.";
         return false;
     }
+    ANativeWindow_acquire(mWindow);
 
     // Set up our OpenGL ES context associated with the default display
     mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
@@ -350,7 +326,12 @@
     mDisplay = EGL_NO_DISPLAY;
 
     // Release the window
-    mSurfaceHolder = nullptr;
+    if (mWindow == nullptr) {
+        return;
+    }
+
+    ANativeWindow_release(mWindow);
+    mWindow = nullptr;
 }
 
 void GlWrapper::showWindow(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy, uint64_t id) {
diff --git a/bluetooth/aidl/vts/Android.bp b/bluetooth/aidl/vts/Android.bp
index 5fc0b2e..ade3bef 100644
--- a/bluetooth/aidl/vts/Android.bp
+++ b/bluetooth/aidl/vts/Android.bp
@@ -16,10 +16,6 @@
     srcs: [
         "VtsHalBluetoothTargetTest.cpp",
         ":BluetoothPacketSources",
-        ":BluetoothHciPacketSources",
-    ],
-    generated_headers: [
-        "BluetoothGeneratedPackets_h",
     ],
     include_dirs: [
         "packages/modules/Bluetooth/system/gd",
@@ -31,7 +27,7 @@
     ],
     static_libs: [
         "android.hardware.bluetooth-V1-ndk",
-        "libbluetooth-types",
+        "libbluetooth_hci_pdl",
     ],
     test_config: "VtsHalBluetoothTargetTest.xml",
     test_suites: [
@@ -57,6 +53,5 @@
     ],
     tidy_disabled_srcs: [
         ":BluetoothPacketSources",
-        ":BluetoothHciPacketSources",
     ],
 }
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 08ad0bb..5f9d605 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -120,7 +120,7 @@
     ABinderProcess_startThreadPool();
 
     SpAIBinder cameraProviderBinder =
-            SpAIBinder(AServiceManager_getService(serviceDescriptor.c_str()));
+            SpAIBinder(AServiceManager_waitForService(serviceDescriptor.c_str()));
     ASSERT_NE(cameraProviderBinder.get(), nullptr);
 
     std::shared_ptr<ICameraProvider> cameraProvider =
diff --git a/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl
index 12bc441..0d1a094 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl
@@ -24,35 +24,47 @@
 @Backing(type="long")
 enum BufferUsage {
     /** bit 0-3 is an enum */
-    CPU_READ_MASK                      = 0xf,
+    CPU_READ_MASK = 0xf,
     /** buffer is never read by CPU */
-    CPU_READ_NEVER                     = 0,
+    CPU_READ_NEVER = 0,
     /** buffer is rarely read by CPU */
-    CPU_READ_RARELY                    = 2,
+    CPU_READ_RARELY = 2,
     /** buffer is often read by CPU */
-    CPU_READ_OFTEN                     = 3,
+    CPU_READ_OFTEN = 3,
 
     /** bit 4-7 is an enum */
-    CPU_WRITE_MASK                     = 0xf << 4,
+    CPU_WRITE_MASK = 0xf << 4,
     /** buffer is never written by CPU */
-    CPU_WRITE_NEVER                    = 0 << 4,
+    CPU_WRITE_NEVER = 0 << 4,
     /** buffer is rarely written by CPU */
-    CPU_WRITE_RARELY                   = 2 << 4,
+    CPU_WRITE_RARELY = 2 << 4,
     /** buffer is often written by CPU */
-    CPU_WRITE_OFTEN                    = 3 << 4,
+    CPU_WRITE_OFTEN = 3 << 4,
 
-    /** buffer is used as a GPU texture */
-    GPU_TEXTURE                        = 1 << 8,
+    /**
+     * Buffer may be used as a GPU texture
+     *
+     * Buffers allocated with this flag must be
+     * texturable both in EGL/GL & Vulkan via
+     * their respective external memory extensions
+     */
+    GPU_TEXTURE = 1 << 8,
 
-    /** buffer is used as a GPU render target */
-    GPU_RENDER_TARGET                  = 1 << 9,
+    /**
+     * Buffer may be used as a GPU render target
+     *
+     * Buffers allocated with this flag must be
+     * renderable both in EGL/GL & Vulkan via
+     * their respective external memory extensions
+     */
+    GPU_RENDER_TARGET = 1 << 9,
 
     /** bit 10 must be zero */
 
     /** buffer is used as a composer HAL overlay layer */
-    COMPOSER_OVERLAY                   = 1 << 11,
+    COMPOSER_OVERLAY = 1 << 11,
     /** buffer is used as a composer HAL client target */
-    COMPOSER_CLIENT_TARGET             = 1 << 12,
+    COMPOSER_CLIENT_TARGET = 1 << 12,
 
     /** bit 13 must be zero */
 
@@ -61,86 +73,86 @@
      * contents (or information derived from the contents) into unprotected
      * memory.
      */
-    PROTECTED                          = 1 << 14,
+    PROTECTED = 1 << 14,
 
     /** buffer is used as a hwcomposer HAL cursor layer */
-    COMPOSER_CURSOR                    = 1 << 15,
+    COMPOSER_CURSOR = 1 << 15,
 
     /** buffer is used as a video encoder input */
-    VIDEO_ENCODER                      = 1 << 16,
+    VIDEO_ENCODER = 1 << 16,
 
     /** buffer is used as a camera HAL output */
-    CAMERA_OUTPUT                      = 1 << 17,
+    CAMERA_OUTPUT = 1 << 17,
 
     /** buffer is used as a camera HAL input */
-    CAMERA_INPUT                       = 1 << 18,
+    CAMERA_INPUT = 1 << 18,
 
     /** bit 19 must be zero */
 
     /** buffer is used as a renderscript allocation */
-    RENDERSCRIPT                       = 1 << 20,
+    RENDERSCRIPT = 1 << 20,
 
     /** bit 21 must be zero */
 
     /** buffer is used as a video decoder output */
-    VIDEO_DECODER                      = 1 << 22,
+    VIDEO_DECODER = 1 << 22,
 
     /** buffer is used as a sensor direct report output */
-    SENSOR_DIRECT_DATA                 = 1 << 23,
+    SENSOR_DIRECT_DATA = 1 << 23,
 
     /**
      * buffer is used as as an OpenGL shader storage or uniform
      * buffer object
      */
-    GPU_DATA_BUFFER                    = 1 << 24,
+    GPU_DATA_BUFFER = 1 << 24,
 
     /** buffer is used as a cube map texture */
-    GPU_CUBE_MAP                       = 1 << 25,
+    GPU_CUBE_MAP = 1 << 25,
 
     /** buffer contains a complete mipmap hierarchy */
-    GPU_MIPMAP_COMPLETE                = 1 << 26,
+    GPU_MIPMAP_COMPLETE = 1 << 26,
 
     /**
      * Buffer is used as input for HEIC encoder.
      */
-    HW_IMAGE_ENCODER                   = 1 << 27,
+    HW_IMAGE_ENCODER = 1 << 27,
 
     /* Bits 28-31 are reserved for vendor usage */
 
     /**
-    * Buffer is used for front-buffer rendering.
-    *
-    * To satisfy an allocation with this usage, the resulting buffer
-    * must operate as equivalent to shared memory for all targets.
-    *
-    * For CPU_USAGE_* other than NEVER, this means the buffer must
-    * "lock in place". The buffers must be directly accessible via mapping.
-    *
-    * For GPU_RENDER_TARGET the buffer must behave equivalent to a
-    * single-buffered EGL surface. For example glFlush must perform
-    * a flush, same as if the default framebuffer was single-buffered.
-    *
-    * For COMPOSER_* the HWC must not perform any caching for this buffer
-    * when submitted for composition. HWCs do not need to do any form
-    * of auto-refresh, and they are allowed to cache composition results between
-    * presents from SF (such as for panel self-refresh), but for any given
-    * present the buffer must be composited from even if it otherwise appears
-    * to be the same as a previous composition.
-    *
-    * If the GPU & HWC supports EGL_SINGLE_BUFFER, then it is recommended that
-    * FRONT_BUFFER usage is supported for the same formats as supported by
-    * EGL_SINGLE_BUFFER. In particular, it is recommended that the following
-    * combination is supported when possible:
-    *    Format = RGBA_8888
-    *    Usage = FRONT_BUFFER | GPU_RENDER_TARGET | COMPOSER_OVERLAY
-    *
-    */
-    FRONT_BUFFER                       = 1L << 32,
+     * Buffer is used for front-buffer rendering.
+     *
+     * To satisfy an allocation with this usage, the resulting buffer
+     * must operate as equivalent to shared memory for all targets.
+     *
+     * For CPU_USAGE_* other than NEVER, this means the buffer must
+     * "lock in place". The buffers must be directly accessible via mapping.
+     *
+     * For GPU_RENDER_TARGET the buffer must behave equivalent to a
+     * single-buffered EGL surface. For example glFlush must perform
+     * a flush, same as if the default framebuffer was single-buffered.
+     *
+     * For COMPOSER_* the HWC must not perform any caching for this buffer
+     * when submitted for composition. HWCs do not need to do any form
+     * of auto-refresh, and they are allowed to cache composition results between
+     * presents from SF (such as for panel self-refresh), but for any given
+     * present the buffer must be composited from even if it otherwise appears
+     * to be the same as a previous composition.
+     *
+     * If the GPU & HWC supports EGL_SINGLE_BUFFER, then it is recommended that
+     * FRONT_BUFFER usage is supported for the same formats as supported by
+     * EGL_SINGLE_BUFFER. In particular, it is recommended that the following
+     * combination is supported when possible:
+     *    Format = RGBA_8888
+     *    Usage = FRONT_BUFFER | GPU_RENDER_TARGET | COMPOSER_OVERLAY
+     *
+     */
+    FRONT_BUFFER = 1L << 32,
 
     /** bits 28-31 are reserved for vendor extensions */
-    VENDOR_MASK                        = 0xf << 28,
+    VENDOR_MASK = 0xf << 28,
 
     /** bits 33-47 must be zero and are reserved for future versions */
     /** bits 48-63 are reserved for vendor extensions */
-    VENDOR_MASK_HI                     = (1L * 0xffff) << 48,
+    VENDOR_MASK_HI = (1L * 0xffff) << 48,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl
index 7377b4b..bb2569f 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl
@@ -42,7 +42,7 @@
     int averageRefreshPeriodNs;
   }
   parcelable NotifyExpectedPresentConfig {
-    int headsUpNs;
-    int timeoutNs;
+    int notifyExpectedPresentHeadsUpNs;
+    int notifyExpectedPresentTimeoutNs;
   }
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index ec54f2a..725c947 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -895,9 +895,9 @@
      *
      * The framework will call this function based on the parameters specified in
      * DisplayConfiguration.VrrConfig:
-     * - timeoutNs specifies the idle time from the previous present command
+     * - notifyExpectedPresentTimeoutNs specifies the idle time from the previous present command
      * where the framework must send the early hint for the next frame.
-     * - headsUpNs specifies minimal time that framework must send
+     * - notifyExpectedPresentHeadsUpNs specifies minimal time that framework must send
      * the early hint before the next frame.
      *
      * The framework can omit calling this API when the next present command matches
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl
index 93667e0..3b241ba 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl
@@ -45,7 +45,7 @@
          * The minimal time in nanoseconds that IComposerClient.notifyExpectedPresent needs to be
          * called ahead of an expectedPresentTime provided on a presentDisplay command.
          */
-        int headsUpNs;
+        int notifyExpectedPresentHeadsUpNs;
 
         /**
          * The time in nanoseconds that represents a timeout from the previous presentDisplay, which
@@ -53,7 +53,7 @@
          * sending the next frame. If set to 0, there is no need to call
          * IComposerClient.notifyExpectedPresent for timeout.
          */
-        int timeoutNs;
+        int notifyExpectedPresentTimeoutNs;
     }
 
     /**
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index 4a8e3b4..1e6f34b 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1274,8 +1274,8 @@
                 if (vrrConfig.notifyExpectedPresentConfig) {
                     const auto& notifyExpectedPresentConfig =
                             *vrrConfig.notifyExpectedPresentConfig;
-                    EXPECT_GT(0, notifyExpectedPresentConfig.headsUpNs);
-                    EXPECT_GE(0, notifyExpectedPresentConfig.timeoutNs);
+                    EXPECT_GT(0, notifyExpectedPresentConfig.notifyExpectedPresentHeadsUpNs);
+                    EXPECT_GE(0, notifyExpectedPresentConfig.notifyExpectedPresentTimeoutNs);
                 }
             }
         }
diff --git a/security/README.md b/security/README.md
new file mode 100644
index 0000000..c5b5ba8
--- /dev/null
+++ b/security/README.md
@@ -0,0 +1,109 @@
+# Security-Related HALs
+
+The `security/` subdirectory holds various security-related HALs.  (The final two sections of this
+document also describe security-related HALs that are in other places under `hardware/interfaces/`.)
+
+The most significant HAL is KeyMint (**`IKeyMintDevice`** in the
+`hardware/interfaces/security/keymint/` directory), which allows access to cryptographic
+functionality where the key material is restricted to a secure environment.  This functionality is
+used by Android system services, and is also made available to apps via Android Keystore.
+
+A KeyMint implementation (or an implementation of its predecessor, Keymaster) that runs in an
+isolated execution environment (e.g. ARM TrustZone) is required for most Android devices; see [CDD
+9.11](https://source.android.com/docs/compatibility/13/android-13-cdd#911_keys_and_credentials).
+
+A device may optionally also support a second KeyMint instance, running in a dedicated secure
+processor; this is known as StrongBox ([CDD
+9.11.2](https://source.android.com/docs/compatibility/13/android-13-cdd#9112_strongbox)).
+
+Two specific features of KeyMint are worth highlighting, as they have an impact on the other
+security-related HALs:
+
+- KeyMint supports keys that can only be used when the operation is authenticated by the user,
+  either by their lock screen knowledge factor (LSKF, e.g. PIN or pattern) or by a strong biometric
+  (e.g. fingerprint).
+- KeyMint supports *attestation* of public keys: when an asymmetric keypair is created, the secure
+  environment produces a chain of signed certificates:
+  - starting from a trusted root certificate
+  - terminating in a leaf certificate that holds the public key; this leaf certificate may also
+    describe the state of the device and the policies attached to the key.
+
+## Authentication Verification
+
+User authentication must also take place in a secure environment (see the final section below), but
+the results of that authentication are communicated to KeyMint via Android.  As such, the
+authentication result (a *hardware auth token*) is signed with a per-boot shared HMAC key known only
+to the secure components, so that it's authenticity can be verified.
+
+If an authenticator, for example GateKeeper (described by the **`IGatekeeper`** HAL in
+`hardware/interfaces/gatekeeper/`), is co-located in the same secure environment as KeyMint, it can
+use a local, vendor-specific, method to communicate the shared HMAC key.
+
+However, if the authenticator is in a different environment than the KeyMint instance then a local
+communication mechanism may not be possible.  For example, a StrongBox KeyMint instance running in a
+separate secure processor may not have a communication channel with a TEE on the main processor.
+
+To allow for this, the **`ISharedSecret`** HAL (in `hardware/interfaces/security/sharedsecret`)
+describes an N-party shared key agreement protocol for per-boot derivation of the shared HMAC key,
+based on a pre-provisioned shared secret.  This HAL can be implemented by any security component
+&ndash; whether KeyMint instance or authenticator &ndash; that needs access to the shared HMAC key.
+
+User authentication operations are also timestamped, but a StrongBox KeyMint instance may not have
+access to a secure time source that is aligned with the authenticator's time source.
+
+To allow for this, the **`ISecureClock`** HAL (in `hardware/interfaces/secureclock`) describes a
+challenge-based timestamp authentication protocol.  This HAL is optional; it need only be
+implemented if there is a KeyMint instance without a secure source of time.
+
+## Attestation Key Provisioning
+
+As noted above, key generation may also generate an attestation certificate chain, which requires
+that the secure environment have access to a signing key which in turn chains back to the Google
+root.
+
+Historically these signing keys were created by Google and provided to vendors for installation in
+batches of devices (to prevent their use as unique device identifiers).  However, this mechanism had
+significant disadvantages, as it required secure handling of key material and only allowed for
+coarse-grained revocation.
+
+The remote key provisioning HAL (**`IRemotelyProvisionedComponent`** in
+`hardware/interfaces/security/rkp/`) provides a mechanism whereby signing certificates for
+attestation can be retrieved at runtime from Google servers based on pre-registered device identity
+information.  This mechanism is used to provision certificates for KeyMint's signing keys, but is
+not restricted to that purpose; it can also be used in other scenarios where keys need to be
+provisioned (for example, for [Widevine](https://developers.google.com/widevine/drm/overview)).
+
+## Keymaster
+
+The Keymaster HAL (**`IKeymasterDevice`** in `hardware/interfaces/keymaster/`) is the historical
+ancestor of many of the HALs here (and may still be present on older devices).  Its functionality is
+effectively the union of the following current HALs:
+
+- **`IKeyMintDevice`**
+- **`ISharedSecret`**
+- **`ISecureClock`**
+
+## Related Authentication HALs
+
+Authentication of users needs to happen in a secure environment, using vendor-specific
+functionality, and so involves the use of one of the following HALs (all of which are outside the
+`security/` subdirectory).
+
+- The **`IGatekeeper`** HAL (in `hardware/interfaces/gatekeeper/`) provides user authentication
+  functionality based on the user's lock-screen knowledge factor (LSKF), including throttling
+  behaviour to prevent attacks.  Authentication tokens produced by this HAL are consumed by KeyMint,
+  validated using the shared HMAC key described above.
+  - The optional **`IWeaver`** HAL (in `hardware/interfaces/weaver`) improves the security of LSKF
+    authentication by converting the user's LSKF into a *synthetic password* via hashing and
+    stretching. This is required to be implemented on a separate secure element, which prevents
+    offline attacks on Gatekeeper storage. Note that Weaver does not directly interact with KeyMint;
+    the synthetic password is fed into Gatekeeper in place of the plain user password, and then
+    Gatekeeper interacts with KeyMint as normal.
+- The **`IFingerprint`** and **`IFace`** HAL definitions (under `hardware/interfaces/biometrics/`)
+  allow access to biometric authentication functionality that is implemented in a secure
+  environment.  Authentication tokens produced by these HALs are consumed by KeyMint, validated
+  using the shared HMAC key described above.
+- The optional **`IConfirmationUI`** HAL (in `hardware/interfaces/confirmationui`) supports
+  functionality where the user confirms that they have seen a specific message in a secure manner.
+  Confirmation tokens produced by this HAL are consumed by KeyMint, validated using the shared HMAC
+  key described above.
diff --git a/security/keymint/aidl/default/service.cpp b/security/keymint/aidl/default/service.cpp
index dc0c618..10cbf07 100644
--- a/security/keymint/aidl/default/service.cpp
+++ b/security/keymint/aidl/default/service.cpp
@@ -44,6 +44,8 @@
 }
 
 int main() {
+    // The global logger object required by keymaster's logging macros in keymaster/logger.h.
+    keymaster::SoftKeymasterLogger km_logger;
     // Zero threads seems like a useless pool, but below we'll join this thread to it, increasing
     // the pool size to 1.
     ABinderProcess_setThreadPoolMaxThreadCount(0);
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index c9c3e4d..780c3d2 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <iomanip>
 #include <iterator>
 #include <memory>
 #include <set>
@@ -420,6 +421,36 @@
     return entryName + " has an invalid value.\n";
 }
 
+std::string checkMapPatchLevelEntry(bool isFactory, const cppbor::Map& devInfo,
+                                    const std::string& entryName) {
+    std::string error = checkMapEntry(isFactory, devInfo, cppbor::UINT, entryName);
+    if (!error.empty()) {
+        return error;
+    }
+
+    if (isFactory) {
+        return "";
+    }
+
+    const std::unique_ptr<cppbor::Item>& val = devInfo.get(entryName);
+    std::string dateString = std::to_string(val->asUint()->unsignedValue());
+    if (dateString.size() == 6) {
+        dateString += "01";
+    }
+    if (dateString.size() != 8) {
+        return entryName + " should in the format YYYYMMDD or YYYYMM\n";
+    }
+
+    std::tm t;
+    std::istringstream ss(dateString);
+    ss >> std::get_time(&t, "%Y%m%d");
+    if (!ss) {
+        return entryName + " should in the format YYYYMMDD or YYYYMM\n";
+    }
+
+    return "";
+}
+
 bool isTeeDeviceInfo(const cppbor::Map& devInfo) {
     return devInfo.get("security_level") && devInfo.get("security_level")->asTstr() &&
            devInfo.get("security_level")->asTstr()->value() == "tee";
@@ -520,6 +551,10 @@
                     error += "Err: Unrecognized key entry: <" + key->asTstr()->value() + ">,\n";
                 }
             }
+            // Checks that only apply to v3.
+            error += checkMapPatchLevelEntry(isFactory, *parsed, "system_patch_level");
+            error += checkMapPatchLevelEntry(isFactory, *parsed, "boot_patch_level");
+            error += checkMapPatchLevelEntry(isFactory, *parsed, "vendor_patch_level");
             FALLTHROUGH_INTENDED;
         case 2:
             for (const auto& entry : kAttestationIdEntrySet) {
diff --git a/security/rkp/aidl/Android.bp b/security/rkp/aidl/Android.bp
index e2ce649..e9e2021 100644
--- a/security/rkp/aidl/Android.bp
+++ b/security/rkp/aidl/Android.bp
@@ -28,6 +28,10 @@
         },
         rust: {
             enabled: true,
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.virt",
+            ],
         },
     },
     versions_with_info: [
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index f8a5540..21c5315 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -185,77 +185,7 @@
      *
      *        In either case, the root is self-signed.
      *
-     *            EekChain = [ + SignedSignatureKey, SignedEek ]
-     *
-     *            SignedSignatureKey = [              ; COSE_Sign1
-     *                protected: bstr .cbor {
-     *                    1 : AlgorithmEdDSA / AlgorithmES256,  ; Algorithm
-     *                },
-     *                unprotected: {},
-     *                payload: bstr .cbor SignatureKeyEd25519 /
-     *                         bstr .cbor SignatureKeyP256,
-     *                signature: bstr PureEd25519(.cbor SignatureKeySignatureInput) /
-     *                           bstr ECDSA(.cbor SignatureKeySignatureInput)
-     *            ]
-     *
-     *            SignatureKeyEd25519 = {             ; COSE_Key
-     *                 1 : 1,                         ; Key type : Octet Key Pair
-     *                 3 : AlgorithmEdDSA,            ; Algorithm
-     *                 -1 : 6,                        ; Curve : Ed25519
-     *                 -2 : bstr                      ; Ed25519 public key
-     *            }
-     *
-     *            SignatureKeyP256 = {                ; COSE_Key
-     *                 1 : 2,                         ; Key type : EC2
-     *                 3 : AlgorithmES256,            ; Algorithm
-     *                 -1 : 1,                        ; Curve: P256
-     *                 -2 : bstr,                     ; X coordinate
-     *                 -3 : bstr                      ; Y coordinate
-     *            }
-     *
-     *            SignatureKeySignatureInput = [
-     *                context: "Signature1",
-     *                body_protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
-     *                external_aad: bstr .size 0,
-     *                payload: bstr .cbor SignatureKeyEd25519 /
-     *                         bstr .cbor SignatureKeyP256
-     *            ]
-     *
-     *            ; COSE_Sign1
-     *            SignedEek = [
-     *                protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
-     *                unprotected: {},
-     *                payload: bstr .cbor EekX25519 / .cbor EekP256,
-     *                signature: bstr PureEd25519(.cbor EekSignatureInput) /
-     *                           bstr ECDSA(.cbor EekSignatureInput)
-     *            ]
-     *
-     *            EekX25519 = {            ; COSE_Key
-     *                1 : 1,               ; Key type : Octet Key Pair
-     *                2 : bstr             ; KID : EEK ID
-     *                3 : -25,             ; Algorithm : ECDH-ES + HKDF-256
-     *                -1 : 4,              ; Curve : X25519
-     *                -2 : bstr            ; X25519 public key, little-endian
-     *            }
-     *
-     *            EekP256 = {              ; COSE_Key
-     *                1 : 2,               ; Key type : EC2
-     *                2 : bstr             ; KID : EEK ID
-     *                3 : -25,             ; Algorithm : ECDH-ES + HKDF-256
-     *                -1 : 1,              ; Curve : P256
-     *                -2 : bstr            ; Sender X coordinate
-     *                -3 : bstr            ; Sender Y coordinate
-     *            }
-     *
-     *            EekSignatureInput = [
-     *                context: "Signature1",
-     *                body_protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
-     *                external_aad: bstr .size 0,
-     *                payload: bstr .cbor EekX25519 / .cbor EekP256
-     *            ]
-     *
-     *            AlgorithmES256 = -7      ; RFC 8152 section 8.1
-     *            AlgorithmEdDSA = -8      ; RFC 8152 section 8.2
+     *        See generateCertificateRequest.cddl for CDDL definitions.
      *
      *        If the contents of endpointEncryptionKey do not match the SignedEek structure above,
      *        the method must return STATUS_INVALID_EEK.
@@ -283,25 +213,9 @@
      *            HMAC-256(EK_mac, .cbor KeysToMacStructure)
      *
      *        Where EK_mac is an ephemeral MAC key, found in ProtectedData (see below).  The MACed
-     *        data is the "tag" field of a COSE_Mac0 structure like:
+     *        data is the "tag" field of a MacedKeys COSE_Mac0 structure.
      *
-     *            MacedKeys = [                            ; COSE_Mac0
-     *                protected : bstr .cbor {
-     *                    1 : 5,                           ; Algorithm : HMAC-256
-     *                },
-     *                unprotected : {},
-     *                ; Payload is PublicKeys from keysToSign argument, in provided order.
-     *                payload: bstr .cbor [ * PublicKey ],
-     *                tag: bstr
-     *            ]
-     *
-     *            KeysToMacStructure = [
-     *                context : "MAC0",
-     *                protected : bstr .cbor { 1 : 5 },    ; Algorithm : HMAC-256
-     *                external_aad : bstr .size 0,
-     *                ; Payload is PublicKeys from keysToSign argument, in provided order.
-     *                payload : bstr .cbor [ * PublicKey ]
-     *            ]
+     *        See generateCertificateRequest.cddl for CDDL definitions.
      */
     byte[] generateCertificateRequest(in boolean testMode, in MacedPublicKey[] keysToSign,
             in byte[] endpointEncryptionCertChain, in byte[] challenge, out DeviceInfo deviceInfo,
@@ -322,168 +236,9 @@
      *        use different semantic data for this field, but the supported sizes must be between 0
      *        and 64 bytes, inclusive.
      *
-     * @return the following CBOR Certificate Signing Request (Csr) serialized into a byte array:
+     * @return a CBOR Certificate Signing Request (Csr) serialized into a byte array.
      *
-     * Csr = AuthenticatedRequest<CsrPayload>
-     *
-     * CsrPayload = [                      ; CBOR Array defining the payload for Csr
-     *     version: 3,                     ; The CsrPayload CDDL Schema version.
-     *     CertificateType,                ; The type of certificate being requested.
-     *     DeviceInfo,                     ; Defined in DeviceInfo.aidl
-     *     KeysToSign,                     ; Provided by the method parameters
-     * ]
-     *
-     *  ; A tstr identifying the type of certificate. The set of supported certificate types may
-     *  ; be extended without requiring a version bump of the HAL. Custom certificate types may
-     *  ; be used, but the provisioning server may reject the request for an unknown certificate
-     *  ; type. The currently defined certificate types are:
-     *  ;  - "widevine"
-     *  ;  - "keymint"
-     *  CertificateType = tstr
-     *
-     * KeysToSign = [ * PublicKey ]   ; Please see MacedPublicKey.aidl for the PublicKey definition.
-     *
-     * AuthenticatedRequest<T> = [
-     *     version: 1,              ; The AuthenticatedRequest CDDL Schema version.
-     *     UdsCerts,
-     *     DiceCertChain,
-     *     SignedData<[
-     *         challenge: bstr .size (0..64), ; Provided by the method parameters
-     *         bstr .cbor T,
-     *     ]>,
-     * ]
-     *
-     * ; COSE_Sign1 (untagged)
-     * SignedData<Data> = [
-     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
-     *     unprotected: {},
-     *     payload: bstr .cbor Data / nil,
-     *     signature: bstr      ; PureEd25519(CDI_Leaf_Priv, SignedDataSigStruct<Data>) /
-     *                          ; ECDSA(CDI_Leaf_Priv, SignedDataSigStruct<Data>)
-     * ]
-     *
-     * ; Sig_structure for SignedData
-     * SignedDataSigStruct<Data> = [
-     *     context: "Signature1",
-     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
-     *     external_aad: bstr .size 0,
-     *     payload: bstr .cbor Data / nil,
-     * ]
-     *
-     * ; UdsCerts allows the platform to provide additional certifications for the UDS_Pub. For
-     * ; example, this could be provided by the hardware vendor, who certifies all of their chips.
-     * ; The SignerName is a free-form string describing who generated the signature. The root
-     * ; certificate will need to be communicated to the verifier out of band, along with the
-     * ; SignerName that is expected for the given root certificate.
-     * UdsCerts = {
-     *     * SignerName => UdsCertChain
-     * }
-     *
-     * ; SignerName is a string identifier that indicates both the signing authority as
-     * ; well as the format of the UdsCertChain
-     * SignerName = tstr
-     *
-     * UdsCertChain = [
-     *     2* X509Certificate       ; Root -> ... -> Leaf. "Root" is the vendor self-signed
-     *                              ; cert, "Leaf" contains UDS_Public. There may also be
-     *                              ; intermediate certificates between Root and Leaf.
-     * ]
-     *
-     * ; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or EdDSA)
-     * X509Certificate = bstr
-     *
-     * ; The DICE Chain contains measurements about the device firmware.
-     * ; The first entry in the DICE Chain is the UDS_Pub, encoded as a COSE_key. All entries
-     * ; after the first describe a link in the boot chain (e.g. bootloaders: BL1, BL2, ... BLN)
-     * ; Note that there is no DiceChainEntry for UDS_pub, only a "bare" COSE_key.
-     * DiceCertChain = [
-     *     PubKeyEd25519 / PubKeyECDSA256 / PubKeyECDSA384,  ; UDS_Pub
-     *     + DiceChainEntry,                ; First CDI_Certificate -> Last CDI_Certificate
-     *                                      ; Last certificate corresponds to KeyMint's DICE key.
-     * ]
-     *
-     * ; This is the signed payload for each entry in the DICE chain. Note that the "Configuration
-     * ; Input Values" described by the Open Profile are not used here. Instead, the DICE chain
-     * ; defines its own configuration values for the Configuration Descriptor field. See
-     * ; the Open Profile for DICE for more details on the fields. SHA256, SHA384 and SHA512 are
-     * ; acceptable hash algorithms. The digest bstr values in the payload are the digest values
-     * ; without any padding. Note that this implies that the digest is a 32-byte bstr for SHA256
-     * ; and a 48-byte bstr for SHA384. This is an intentional, minor deviation from Open Profile
-     * ; for DICE, which specifies all digests are 64 bytes.
-     * DiceChainEntryPayload = {                    ; CWT [RFC8392]
-     *     1 : tstr,                                ; Issuer
-     *     2 : tstr,                                ; Subject
-     *     -4670552 : bstr .cbor PubKeyEd25519 /
-     *                bstr .cbor PubKeyECDSA256 /
-     *                bstr .cbor PubKeyECDSA384,    ; Subject Public Key
-     *     -4670553 : bstr                          ; Key Usage
-     *
-     *     ; NOTE: All of the following fields may be omitted for a "Degenerate DICE Chain", as
-     *     ;       described above.
-     *     -4670545 : bstr,                         ; Code Hash
-     *     ? -4670546 : bstr,                       ; Code Descriptor
-     *     -4670547 : bstr,                         ; Configuration Hash
-     *     -4670548 : bstr .cbor {                  ; Configuration Descriptor
-     *         ? -70002 : tstr,                         ; Component name
-     *         ? -70003 : int / tstr,                   ; Component version
-     *         ? -70004 : null,                         ; Resettable
-     *         ? -70005 : uint,                         ; Security version
-     *     },
-     *     -4670549 : bstr,                         ; Authority Hash
-     *     ? -4670550 : bstr,                       ; Authority Descriptor
-     *     -4670551 : bstr,                         ; Mode
-     * }
-     *
-     * ; Each entry in the DICE chain is a DiceChainEntryPayload signed by the key from the previous
-     * ; entry in the DICE chain array.
-     * DiceChainEntry = [                            ; COSE_Sign1 (untagged)
-     *     protected : bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
-     *     unprotected: {},
-     *     payload: bstr .cbor DiceChainEntryPayload,
-     *     signature: bstr ; PureEd25519(SigningKey, DiceChainEntryInput) /
-     *                     ; ECDSA(SigningKey, DiceChainEntryInput)
-     *                     ; See RFC 8032 for details of how to encode the signature value
-     *                     ; for Ed25519.
-     * ]
-     *
-     * DiceChainEntryInput = [
-     *     context: "Signature1",
-     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
-     *     external_aad: bstr .size 0,
-     *     payload: bstr .cbor DiceChainEntryPayload
-     * ]
-     *
-     * ; The following section defines some types that are reused throughout the above
-     * ; data structures.
-     * ; NOTE: Integer encoding is different for Ed25519 and P256 keys:
-     * ;       - Ed25519 is LE: https://www.rfc-editor.org/rfc/rfc8032#section-3.1
-     * ;       - P256 is BE: https://www.secg.org/sec1-v2.pdf#page=19 (section 2.3.7)
-     * PubKeyEd25519 = {                ; COSE_Key
-     *     1 : 1,                       ; Key type : octet key pair
-     *     3 : AlgorithmEdDSA,          ; Algorithm : EdDSA
-     *     -1 : 6,                      ; Curve : Ed25519
-     *     -2 : bstr                    ; X coordinate, little-endian
-     * }
-     *
-     * PubKeyECDSA256 = {               ; COSE_Key
-     *     1 : 2,                       ; Key type : EC2
-     *     3 : AlgorithmES256,          ; Algorithm : ECDSA w/ SHA-256
-     *     -1 : 1,                      ; Curve: P256
-     *     -2 : bstr,                   ; X coordinate, big-endian
-     *     -3 : bstr                    ; Y coordinate, big-endian
-     * }
-     *
-     * PubKeyECDSA384 = {               ; COSE_Key
-     *     1 : 2,                       ; Key type : EC2
-     *     3 : AlgorithmES384,          ; Algorithm : ECDSA w/ SHA-384
-     *     -1 : 2,                      ; Curve: P384
-     *     -2 : bstr,                   ; X coordinate
-     *     -3 : bstr                    ; Y coordinate
-     * }
-     *
-     * AlgorithmES256 = -7
-     * AlgorithmES384 = -35
-     * AlgorithmEdDSA = -8
+     *         See generateCertificateRequestV2.cddl for CDDL definitions.
      */
     byte[] generateCertificateRequestV2(in MacedPublicKey[] keysToSign, in byte[] challenge);
 }
diff --git a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequest.cddl b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequest.cddl
new file mode 100644
index 0000000..82930bc
--- /dev/null
+++ b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequest.cddl
@@ -0,0 +1,92 @@
+; CDDL for the deprecated version 1 generateCertificateRequest method
+; in IRemotelyProvisionedComponent.aidl
+
+EekChain = [ + SignedSignatureKey, SignedEek ]
+
+SignedSignatureKey = [              ; COSE_Sign1
+    protected: bstr .cbor {
+        1 : AlgorithmEdDSA / AlgorithmES256,  ; Algorithm
+    },
+    unprotected: {},
+    payload: bstr .cbor SignatureKeyEd25519 /
+                bstr .cbor SignatureKeyP256,
+    signature: bstr PureEd25519(.cbor SignatureKeySignatureInput) /
+                bstr ECDSA(.cbor SignatureKeySignatureInput)
+]
+
+SignatureKeyEd25519 = {             ; COSE_Key
+        1 : 1,                         ; Key type : Octet Key Pair
+        3 : AlgorithmEdDSA,            ; Algorithm
+        -1 : 6,                        ; Curve : Ed25519
+        -2 : bstr                      ; Ed25519 public key
+}
+
+SignatureKeyP256 = {                ; COSE_Key
+        1 : 2,                         ; Key type : EC2
+        3 : AlgorithmES256,            ; Algorithm
+        -1 : 1,                        ; Curve: P256
+        -2 : bstr,                     ; X coordinate
+        -3 : bstr                      ; Y coordinate
+}
+
+SignatureKeySignatureInput = [
+    context: "Signature1",
+    body_protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+    external_aad: bstr .size 0,
+    payload: bstr .cbor SignatureKeyEd25519 /
+                bstr .cbor SignatureKeyP256
+]
+
+; COSE_Sign1
+SignedEek = [
+    protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+    unprotected: {},
+    payload: bstr .cbor EekX25519 / .cbor EekP256,
+    signature: bstr PureEd25519(.cbor EekSignatureInput) /
+                bstr ECDSA(.cbor EekSignatureInput)
+]
+
+EekX25519 = {            ; COSE_Key
+    1 : 1,               ; Key type : Octet Key Pair
+    2 : bstr             ; KID : EEK ID
+    3 : -25,             ; Algorithm : ECDH-ES + HKDF-256
+    -1 : 4,              ; Curve : X25519
+    -2 : bstr            ; X25519 public key, little-endian
+}
+
+EekP256 = {              ; COSE_Key
+    1 : 2,               ; Key type : EC2
+    2 : bstr             ; KID : EEK ID
+    3 : -25,             ; Algorithm : ECDH-ES + HKDF-256
+    -1 : 1,              ; Curve : P256
+    -2 : bstr            ; Sender X coordinate
+    -3 : bstr            ; Sender Y coordinate
+}
+
+EekSignatureInput = [
+    context: "Signature1",
+    body_protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+    external_aad: bstr .size 0,
+    payload: bstr .cbor EekX25519 / .cbor EekP256
+]
+
+AlgorithmES256 = -7      ; RFC 8152 section 8.1
+AlgorithmEdDSA = -8      ; RFC 8152 section 8.2
+
+MacedKeys = [                            ; COSE_Mac0
+    protected : bstr .cbor {
+        1 : 5,                           ; Algorithm : HMAC-256
+    },
+    unprotected : {},
+    ; Payload is PublicKeys from keysToSign argument, in provided order.
+    payload: bstr .cbor [ * PublicKey ],
+    tag: bstr
+]
+
+KeysToMacStructure = [
+    context : "MAC0",
+    protected : bstr .cbor { 1 : 5 },    ; Algorithm : HMAC-256
+    external_aad : bstr .size 0,
+    ; Payload is PublicKeys from keysToSign argument, in provided order.
+    payload : bstr .cbor [ * PublicKey ]
+]
diff --git a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
new file mode 100644
index 0000000..ea71f98
--- /dev/null
+++ b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
@@ -0,0 +1,163 @@
+; CDDL for the generateCertificateRequestV2 method in
+; IRemotelyProvisionedComponent.aidl
+
+Csr = AuthenticatedRequest<CsrPayload>
+
+CsrPayload = [                      ; CBOR Array defining the payload for Csr
+    version: 3,                     ; The CsrPayload CDDL Schema version.
+    CertificateType,                ; The type of certificate being requested.
+    DeviceInfo,                     ; Defined in DeviceInfo.aidl
+    KeysToSign,                     ; Provided by the method parameters
+]
+
+; A tstr identifying the type of certificate. The set of supported certificate types may
+; be extended without requiring a version bump of the HAL. Custom certificate types may
+; be used, but the provisioning server may reject the request for an unknown certificate
+; type. The currently defined certificate types are:
+;  - "widevine"
+;  - "keymint"
+CertificateType = tstr
+
+KeysToSign = [ * PublicKey ]   ; Please see MacedPublicKey.aidl for the PublicKey definition.
+
+AuthenticatedRequest<T> = [
+    version: 1,              ; The AuthenticatedRequest CDDL Schema version.
+    UdsCerts,
+    DiceCertChain,
+    SignedData<[
+        challenge: bstr .size (0..64), ; Provided by the method parameters
+        bstr .cbor T,
+    ]>,
+]
+
+; COSE_Sign1 (untagged)
+SignedData<Data> = [
+    protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
+    unprotected: {},
+    payload: bstr .cbor Data / nil,
+    signature: bstr     ; PureEd25519(CDI_Leaf_Priv, SignedDataSigStruct<Data>) /
+                        ; ECDSA(CDI_Leaf_Priv, SignedDataSigStruct<Data>)
+]
+
+; Sig_structure for SignedData
+SignedDataSigStruct<Data> = [
+    context: "Signature1",
+    protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
+    external_aad: bstr .size 0,
+    payload: bstr .cbor Data / nil,
+]
+
+; UdsCerts allows the platform to provide additional certifications for the UDS_Pub. For
+; example, this could be provided by the hardware vendor, who certifies all of their chips.
+; The SignerName is a free-form string describing who generated the signature. The root
+; certificate will need to be communicated to the verifier out of band, along with the
+; SignerName that is expected for the given root certificate.
+UdsCerts = {
+    * SignerName => UdsCertChain
+}
+
+; SignerName is a string identifier that indicates both the signing authority as
+; well as the format of the UdsCertChain
+SignerName = tstr
+
+UdsCertChain = [
+    2* X509Certificate      ; Root -> ... -> Leaf. "Root" is the vendor self-signed
+                            ; cert, "Leaf" contains UDS_Public. There may also be
+                            ; intermediate certificates between Root and Leaf.
+]
+
+; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or EdDSA)
+X509Certificate = bstr
+
+; The DICE Chain contains measurements about the device firmware.
+; The first entry in the DICE Chain is the UDS_Pub, encoded as a COSE_key. All entries
+; after the first describe a link in the boot chain (e.g. bootloaders: BL1, BL2, ... BLN)
+; Note that there is no DiceChainEntry for UDS_pub, only a "bare" COSE_key.
+DiceCertChain = [
+    PubKeyEd25519 / PubKeyECDSA256 / PubKeyECDSA384,  ; UDS_Pub
+    + DiceChainEntry,               ; First CDI_Certificate -> Last CDI_Certificate
+                                    ; Last certificate corresponds to KeyMint's DICE key.
+]
+
+; This is the signed payload for each entry in the DICE chain. Note that the "Configuration
+; Input Values" described by the Open Profile are not used here. Instead, the DICE chain
+; defines its own configuration values for the Configuration Descriptor field. See
+; the Open Profile for DICE for more details on the fields. SHA256, SHA384 and SHA512 are
+; acceptable hash algorithms. The digest bstr values in the payload are the digest values
+; without any padding. Note that this implies that the digest is a 32-byte bstr for SHA256
+; and a 48-byte bstr for SHA384. This is an intentional, minor deviation from Open Profile
+; for DICE, which specifies all digests are 64 bytes.
+DiceChainEntryPayload = {                    ; CWT [RFC8392]
+    1 : tstr,                                ; Issuer
+    2 : tstr,                                ; Subject
+    -4670552 : bstr .cbor PubKeyEd25519 /
+            bstr .cbor PubKeyECDSA256 /
+            bstr .cbor PubKeyECDSA384,    ; Subject Public Key
+    -4670553 : bstr                          ; Key Usage
+
+    ; NOTE: All of the following fields may be omitted for a "Degenerate DICE Chain", as
+    ;       described above.
+    -4670545 : bstr,                         ; Code Hash
+    ? -4670546 : bstr,                       ; Code Descriptor
+    -4670547 : bstr,                         ; Configuration Hash
+    -4670548 : bstr .cbor {                  ; Configuration Descriptor
+        ? -70002 : tstr,                         ; Component name
+        ? -70003 : int / tstr,                   ; Component version
+        ? -70004 : null,                         ; Resettable
+        ? -70005 : uint,                         ; Security version
+    },
+    -4670549 : bstr,                         ; Authority Hash
+    ? -4670550 : bstr,                       ; Authority Descriptor
+    -4670551 : bstr,                         ; Mode
+}
+
+; Each entry in the DICE chain is a DiceChainEntryPayload signed by the key from the previous
+; entry in the DICE chain array.
+DiceChainEntry = [                            ; COSE_Sign1 (untagged)
+    protected : bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
+    unprotected: {},
+    payload: bstr .cbor DiceChainEntryPayload,
+    signature: bstr ; PureEd25519(SigningKey, DiceChainEntryInput) /
+                    ; ECDSA(SigningKey, DiceChainEntryInput)
+                    ; See RFC 8032 for details of how to encode the signature value
+                    ; for Ed25519.
+]
+
+DiceChainEntryInput = [
+    context: "Signature1",
+    protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
+    external_aad: bstr .size 0,
+    payload: bstr .cbor DiceChainEntryPayload
+]
+
+; The following section defines some types that are reused throughout the above
+; data structures.
+; NOTE: Integer encoding is different for Ed25519 and P256 keys:
+;       - Ed25519 is LE: https://www.rfc-editor.org/rfc/rfc8032#section-3.1
+;       - P256 is BE: https://www.secg.org/sec1-v2.pdf#page=19 (section 2.3.7)
+PubKeyEd25519 = {                ; COSE_Key
+    1 : 1,                       ; Key type : octet key pair
+    3 : AlgorithmEdDSA,          ; Algorithm : EdDSA
+    -1 : 6,                      ; Curve : Ed25519
+    -2 : bstr                    ; X coordinate, little-endian
+}
+
+PubKeyECDSA256 = {               ; COSE_Key
+    1 : 2,                       ; Key type : EC2
+    3 : AlgorithmES256,          ; Algorithm : ECDSA w/ SHA-256
+    -1 : 1,                      ; Curve: P256
+    -2 : bstr,                   ; X coordinate, big-endian
+    -3 : bstr                    ; Y coordinate, big-endian
+}
+
+PubKeyECDSA384 = {               ; COSE_Key
+    1 : 2,                       ; Key type : EC2
+    3 : AlgorithmES384,          ; Algorithm : ECDSA w/ SHA-384
+    -1 : 2,                      ; Curve: P384
+    -2 : bstr,                   ; X coordinate
+    -3 : bstr                    ; Y coordinate
+}
+
+AlgorithmES256 = -7
+AlgorithmES384 = -35
+AlgorithmEdDSA = -8
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
index 02f8209..fae30c0 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -89,6 +89,24 @@
     ChipModeId mode_id;
     return configureChipToSupportIfaceTypeInternal(wifi_chip, type, &mode_id);
 }
+
+bool doesChipSupportIfaceTypeInternal(const sp<IWifiChip>& wifi_chip,
+                                         IfaceType type) {
+    ChipModeId mode_id;
+    if (!wifi_chip.get()) {
+        return false;
+    }
+    const auto& status_and_modes = HIDL_INVOKE(wifi_chip, getAvailableModes);
+    if (status_and_modes.first.code != WifiStatusCode::SUCCESS) {
+        return false;
+    }
+    if (!findAnyModeSupportingIfaceType(type, status_and_modes.second,
+                                        &mode_id)) {
+        return false;
+    }
+
+    return true;
+}
 }  // namespace
 
 sp<IWifi> getWifi(const std::string& instance_name) {
@@ -205,6 +223,11 @@
                                                    configured_mode_id);
 }
 
+bool doesChipSupportIfaceType(const sp<IWifiChip>& wifi_chip,
+                                     IfaceType type) {
+    return doesChipSupportIfaceTypeInternal(wifi_chip, type);
+}
+
 void stopWifi(const std::string& instance_name) {
     sp<IWifi> wifi = IWifi::getService(instance_name);
     ASSERT_NE(wifi, nullptr);
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
index 62c015c..876c316 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
@@ -49,6 +49,10 @@
     const android::sp<android::hardware::wifi::V1_0::IWifiChip>& wifi_chip,
     android::hardware::wifi::V1_0::IfaceType type,
     android::hardware::wifi::V1_0::ChipModeId* configured_mode_id);
+// Check whether wifi chip supports given interface type mode
+bool doesChipSupportIfaceType(
+        const android::sp<android::hardware::wifi::V1_0::IWifiChip>& wifi_chip,
+        android::hardware::wifi::V1_0::IfaceType type);
 // Used to trigger IWifi.stop() at the end of every test.
 void stopWifi(const std::string& instance_name);
 uint32_t getChipCapabilitiesLatest(
diff --git a/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp
index 424f934..c3bd4d7 100644
--- a/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp
+++ b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -58,12 +58,16 @@
             "wifi_softap_bridged_ap_supported");
         // Make sure to start with a clean state
         stopWifi(GetInstanceName());
+        // Read AP mode capabilities from the wifi chip modes
+        sp<IWifiChip> wifi_chip_ = getWifiChip_1_5(GetInstanceName());
+        isApModeSupport_ = doesChipSupportIfaceType(wifi_chip_, IfaceType::AP);
     }
 
     virtual void TearDown() override { stopWifi(GetInstanceName()); }
 
    protected:
     bool isBridgedSupport_ = false;
+    bool isApModeSupport_ = false;
     std::string GetInstanceName() { return GetParam(); }
 };
 
@@ -83,6 +87,7 @@
  * resetToFactoryMacAddress in non-bridged mode
  */
 TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressTest) {
+    if (!isApModeSupport_) GTEST_SKIP() << "Missing AP support";
     sp<IWifiApIface> wifi_ap_iface = getWifiApIface_1_5(GetInstanceName());
     ASSERT_NE(nullptr, wifi_ap_iface.get());
     const auto& status = HIDL_INVOKE(wifi_ap_iface, resetToFactoryMacAddress);
@@ -93,6 +98,7 @@
  * getBridgedInstances in non-bridged mode
  */
 TEST_P(WifiApIfaceHidlTest, getBridgedInstancesTest) {
+    if (!isApModeSupport_) GTEST_SKIP() << "Missing AP support";
     sp<IWifiApIface> wifi_ap_iface = getWifiApIface_1_5(GetInstanceName());
     ASSERT_NE(nullptr, wifi_ap_iface.get());
     const auto& status_and_instances =
diff --git a/wifi/aidl/default/wifi_feature_flags.cpp b/wifi/aidl/default/wifi_feature_flags.cpp
index 3c9f042..35b4b4a 100644
--- a/wifi/aidl/default/wifi_feature_flags.cpp
+++ b/wifi/aidl/default/wifi_feature_flags.cpp
@@ -122,6 +122,7 @@
 #define AP IfaceConcurrencyType::AP
 #define AP_BRIDGED IfaceConcurrencyType::AP_BRIDGED
 #define P2P IfaceConcurrencyType::P2P
+#undef NAN  // undefine NAN from math.h
 #define NAN IfaceConcurrencyType::NAN_IFACE
 static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
         {kMainModeId, legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS})},
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
index 75d6252..56f285d 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
@@ -41,10 +41,9 @@
 using ::android::wifi_system::HostapdManager;
 using ::android::wifi_system::SupplicantManager;
 
-namespace {
 // Helper function to initialize the driver and firmware to AP mode
 // using the vendor HAL HIDL interface.
-void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+void initializeDriverAndFirmware(const std::string& wifi_instance_name) {
     if (getWifi(wifi_instance_name) != nullptr) {
         sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
         ChipModeId mode_id;
@@ -57,21 +56,20 @@
 
 // Helper function to deinitialize the driver and firmware
 // using the vendor HAL HIDL interface.
-void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name) {
     if (getWifi(wifi_instance_name) != nullptr) {
         stopWifi(wifi_instance_name);
     } else {
         LOG(WARNING) << __func__ << ": Vendor HAL not supported";
     }
 }
-}  // namespace
 
 void stopSupplicantIfNeeded(const std::string& instance_name) {
     SupplicantManager supplicant_manager;
     if (supplicant_manager.IsSupplicantRunning()) {
         LOG(INFO) << "Supplicant is running, stop supplicant first.";
         ASSERT_TRUE(supplicant_manager.StopSupplicant());
-        deInitilializeDriverAndFirmware(instance_name);
+        deInitializeDriverAndFirmware(instance_name);
         ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
     }
 }
@@ -80,13 +78,13 @@
     HostapdManager hostapd_manager;
 
     ASSERT_TRUE(hostapd_manager.StopHostapd());
-    deInitilializeDriverAndFirmware(instance_name);
+    deInitializeDriverAndFirmware(instance_name);
 }
 
 void startHostapdAndWaitForHidlService(
     const std::string& wifi_instance_name,
     const std::string& hostapd_instance_name) {
-    initilializeDriverAndFirmware(wifi_instance_name);
+    initializeDriverAndFirmware(wifi_instance_name);
 
     HostapdManager hostapd_manager;
     ASSERT_TRUE(hostapd_manager.StartHostapd());
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
index 5cb4f01..893de1e 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
@@ -33,5 +33,9 @@
 
 bool is_1_1(const android::sp<android::hardware::wifi::hostapd::V1_0::IHostapd>&
                 hostapd);
+// Used to initialize/deinitialize the driver and firmware at the
+// beginning and end of each test.
+void initializeDriverAndFirmware(const std::string& wifi_instance_name);
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name);
 
 #endif /* HOSTAPD_HIDL_TEST_UTILS_H */
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index 33318a4..ff35056 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -37,6 +37,7 @@
         "android.hardware.wifi@1.5",
         "android.hardware.wifi@1.6",
         "android.hardware.wifi-V1-ndk",
+        "libwifi-system",
         "libwifi-system-iface",
         "VtsHalWifiTargetTestUtil",
     ],
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index efd1538..137537d 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -32,6 +32,7 @@
 #include <wifi_hidl_test_utils_1_5.h>
 #include <wifi_hidl_test_utils_1_6.h>
 
+#include "hostapd_test_utils.h"
 #include "wifi_aidl_test_utils.h"
 
 using aidl::android::hardware::wifi::hostapd::BandMask;
@@ -56,10 +57,7 @@
 const int kIfaceChannel = 6;
 const int kIfaceInvalidChannel = 567;
 const std::vector<uint8_t> kTestZeroMacAddr(6, 0x0);
-const Ieee80211ReasonCode kTestDisconnectReasonCode =
-    Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
-const std::string kWifiAidlInstanceNameStr = std::string() + IWifi::descriptor + "/default";
-const char* kWifiAidlInstanceName = kWifiAidlInstanceNameStr.c_str();
+const Ieee80211ReasonCode kTestDisconnectReasonCode = Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
 
 inline BandMask operator|(BandMask a, BandMask b) {
     return static_cast<BandMask>(static_cast<int32_t>(a) |
@@ -70,10 +68,13 @@
 class HostapdAidl : public testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        hostapd = IHostapd::fromBinder(ndk::SpAIBinder(
-            AServiceManager_waitForService(GetParam().c_str())));
+        disableHalsAndFramework();
+        initializeHostapdAndVendorHal(GetParam());
+
+        hostapd = getHostapd(GetParam());
         ASSERT_NE(hostapd, nullptr);
         EXPECT_TRUE(hostapd->setDebugParams(DebugLevel::EXCESSIVE).isOk());
+
         isAcsSupport = testing::checkSubstringInCommandOutput(
             "/system/bin/cmd wifi get-softap-supported-features",
             "wifi_softap_acs_supported");
@@ -81,81 +82,23 @@
             "/system/bin/cmd wifi get-softap-supported-features",
             "wifi_softap_wpa3_sae_supported");
         isBridgedSupport = testing::checkSubstringInCommandOutput(
-            "/system/bin/cmd wifi get-softap-supported-features",
-            "wifi_softap_bridged_ap_supported");
-        if (!isAidlServiceAvailable(kWifiAidlInstanceName)) {
-            const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
-                    ::android::hardware::wifi::V1_0::IWifi::descriptor);
-            EXPECT_NE(0, instances.size());
-            wifiHidlInstanceName = instances[0];
-        }
+                "/system/bin/cmd wifi get-softap-supported-features",
+                "wifi_softap_bridged_ap_supported");
     }
 
     virtual void TearDown() override {
-        stopVendorHal();
         hostapd->terminate();
         //  Wait 3 seconds to allow terminate to complete
         sleep(3);
+        stopHostapdAndVendorHal();
+        startWifiFramework();
     }
 
     std::shared_ptr<IHostapd> hostapd;
-    std::string wifiHidlInstanceName;
     bool isAcsSupport;
     bool isWpa3SaeSupport;
     bool isBridgedSupport;
 
-    void stopVendorHal() {
-        if (isAidlServiceAvailable(kWifiAidlInstanceName)) {
-            // HIDL and AIDL versions of getWifi() take different arguments
-            // i.e. const char* vs string
-            if (getWifi(kWifiAidlInstanceName) != nullptr) {
-                stopWifiService(kWifiAidlInstanceName);
-            }
-        } else {
-            if (getWifi(wifiHidlInstanceName) != nullptr) {
-                stopWifi(wifiHidlInstanceName);
-            }
-        }
-    }
-
-    std::string setupApIfaceAndGetName(bool isBridged) {
-        if (isAidlServiceAvailable(kWifiAidlInstanceName)) {
-            return setupApIfaceAndGetNameAidl(isBridged);
-        } else {
-            return setupApIfaceAndGetNameHidl(isBridged);
-        }
-    }
-
-    std::string setupApIfaceAndGetNameAidl(bool isBridged) {
-        std::shared_ptr<IWifiApIface> wifi_ap_iface;
-        if (isBridged) {
-            wifi_ap_iface = getBridgedWifiApIface(kWifiAidlInstanceName);
-        } else {
-            wifi_ap_iface = getWifiApIface(kWifiAidlInstanceName);
-        }
-        EXPECT_NE(nullptr, wifi_ap_iface.get());
-
-        std::string ap_iface_name;
-        auto status = wifi_ap_iface->getName(&ap_iface_name);
-        EXPECT_TRUE(status.isOk());
-        return ap_iface_name;
-    }
-
-    std::string setupApIfaceAndGetNameHidl(bool isBridged) {
-        android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
-        if (isBridged) {
-            wifi_ap_iface = getBridgedWifiApIface_1_6(wifiHidlInstanceName);
-        } else {
-            wifi_ap_iface = getWifiApIface_1_5(wifiHidlInstanceName);
-        }
-        EXPECT_NE(nullptr, wifi_ap_iface.get());
-
-        const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
-        EXPECT_EQ(android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS,
-                  status_and_name.first.code);
-        return status_and_name.second;
-    }
-
     IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
         IfaceParams iface_params;
         ChannelParams channelParams;
diff --git a/wifi/hostapd/aidl/vts/functional/hostapd_aidl_test_utils.h b/wifi/hostapd/aidl/vts/functional/hostapd_aidl_test_utils.h
new file mode 100644
index 0000000..93540b2
--- /dev/null
+++ b/wifi/hostapd/aidl/vts/functional/hostapd_aidl_test_utils.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <android-base/logging.h>
+
+#include "wifi_aidl_test_utils.h"
+
+namespace {
+
+const std::string kWifiInstanceNameStr = std::string() + IWifi::descriptor + "/default";
+const char* kWifiInstanceName = kWifiInstanceNameStr.c_str();
+
+}  // namespace
+
+namespace HostapdAidlTestUtils {
+
+bool useAidlService() {
+    return isAidlServiceAvailable(kWifiInstanceName);
+}
+
+void startAndConfigureVendorHal() {
+    if (getWifi(kWifiInstanceName) != nullptr) {
+        std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(kWifiInstanceName);
+        int mode_id;
+        EXPECT_TRUE(configureChipToSupportConcurrencyType(wifi_chip, IfaceConcurrencyType::AP,
+                                                          &mode_id));
+    } else {
+        LOG(ERROR) << "Unable to initialize Vendor HAL";
+    }
+}
+
+void stopVendorHal() {
+    if (getWifi(kWifiInstanceName) != nullptr) {
+        stopWifiService(kWifiInstanceName);
+    } else {
+        LOG(ERROR) << "Unable to stop Vendor HAL";
+    }
+}
+
+std::string setupApIfaceAndGetName(bool isBridged) {
+    std::shared_ptr<IWifiApIface> wifi_ap_iface;
+    if (isBridged) {
+        wifi_ap_iface = getBridgedWifiApIface(kWifiInstanceName);
+    } else {
+        wifi_ap_iface = getWifiApIface(kWifiInstanceName);
+    }
+
+    EXPECT_TRUE(wifi_ap_iface.get() != nullptr);
+    if (!wifi_ap_iface.get()) {
+        LOG(ERROR) << "Unable to create iface. isBridged=" << isBridged;
+        return "";
+    }
+
+    std::string ap_iface_name;
+    auto status = wifi_ap_iface->getName(&ap_iface_name);
+    EXPECT_TRUE(status.isOk());
+    if (!status.isOk()) {
+        LOG(ERROR) << "Unable to retrieve iface name. isBridged=" << isBridged;
+        return "";
+    }
+    return ap_iface_name;
+}
+
+}  // namespace HostapdAidlTestUtils
diff --git a/wifi/hostapd/aidl/vts/functional/hostapd_legacy_test_utils.h b/wifi/hostapd/aidl/vts/functional/hostapd_legacy_test_utils.h
new file mode 100644
index 0000000..fb59dc2
--- /dev/null
+++ b/wifi/hostapd/aidl/vts/functional/hostapd_legacy_test_utils.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/logging.h>
+
+#include "hostapd_hidl_test_utils.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::WifiStatus;
+
+namespace {
+
+std::string getWifiInstanceName() {
+    const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
+            ::android::hardware::wifi::V1_0::IWifi::descriptor);
+    EXPECT_NE(0, instances.size());
+    return instances.size() != 0 ? instances[0] : "";
+}
+
+}  // namespace
+
+namespace HostapdLegacyTestUtils {
+
+void startAndConfigureVendorHal() {
+    initializeDriverAndFirmware(getWifiInstanceName());
+}
+
+void stopVendorHal() {
+    deInitializeDriverAndFirmware(getWifiInstanceName());
+}
+
+std::string setupApIfaceAndGetName(bool isBridged) {
+    android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
+    if (isBridged) {
+        wifi_ap_iface = getBridgedWifiApIface_1_6(getWifiInstanceName());
+    } else {
+        wifi_ap_iface = getWifiApIface_1_5(getWifiInstanceName());
+    }
+
+    EXPECT_TRUE(wifi_ap_iface.get() != nullptr);
+    if (!wifi_ap_iface.get()) {
+        LOG(ERROR) << "Unable to create iface. isBridged=" << isBridged;
+        return "";
+    }
+
+    const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
+    EXPECT_TRUE(status_and_name.first.code ==
+                android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS);
+    if (status_and_name.first.code != android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS) {
+        LOG(ERROR) << "Unable to retrieve iface name. isBridged=" << isBridged;
+        return "";
+    }
+    return status_and_name.second;
+}
+
+}  // namespace HostapdLegacyTestUtils
diff --git a/wifi/hostapd/aidl/vts/functional/hostapd_test_utils.h b/wifi/hostapd/aidl/vts/functional/hostapd_test_utils.h
new file mode 100644
index 0000000..feee2c8
--- /dev/null
+++ b/wifi/hostapd/aidl/vts/functional/hostapd_test_utils.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
+#include <android-base/logging.h>
+#include <wifi_system/hostapd_manager.h>
+#include <wifi_system/supplicant_manager.h>
+
+#include "hostapd_aidl_test_utils.h"
+#include "hostapd_legacy_test_utils.h"
+
+using aidl::android::hardware::wifi::hostapd::IHostapd;
+using android::wifi_system::HostapdManager;
+using android::wifi_system::SupplicantManager;
+
+namespace {
+
+void startAndConfigureVendorHal() {
+    if (HostapdAidlTestUtils::useAidlService()) {
+        HostapdAidlTestUtils::startAndConfigureVendorHal();
+    } else {
+        HostapdLegacyTestUtils::startAndConfigureVendorHal();
+    }
+}
+
+void stopVendorHal() {
+    if (HostapdAidlTestUtils::useAidlService()) {
+        HostapdAidlTestUtils::stopVendorHal();
+    } else {
+        HostapdLegacyTestUtils::stopVendorHal();
+    }
+}
+
+void stopHostapd() {
+    HostapdManager hostapd_manager;
+    ASSERT_TRUE(hostapd_manager.StopHostapd());
+}
+
+void waitForSupplicantState(bool enable) {
+    SupplicantManager supplicant_manager;
+    int count = 50;  // wait at most 5 seconds
+    while (count-- > 0) {
+        if (supplicant_manager.IsSupplicantRunning() == enable) {
+            return;
+        }
+        usleep(100000);  // 100 ms
+    }
+    LOG(ERROR) << "Unable to " << (enable ? "start" : "stop") << " supplicant";
+}
+
+void toggleWifiFramework(bool enable) {
+    if (enable) {
+        std::system("svc wifi enable");
+        std::system("cmd wifi set-scan-always-available enabled");
+        waitForSupplicantState(true);
+    } else {
+        std::system("svc wifi disable");
+        std::system("cmd wifi set-scan-always-available disabled");
+        waitForSupplicantState(false);
+    }
+}
+
+}  // namespace
+
+std::shared_ptr<IHostapd> getHostapd(const std::string& hostapd_instance_name) {
+    return IHostapd::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(hostapd_instance_name.c_str())));
+}
+
+/**
+ * Disable the Wifi framework, hostapd, and vendor HAL.
+ *
+ * Note: The framework should be disabled to avoid having
+ *       any other clients to the HALs during testing.
+ */
+void disableHalsAndFramework() {
+    toggleWifiFramework(false);
+    stopHostapd();
+    stopVendorHal();
+
+    // Wait for the services to stop.
+    sleep(3);
+}
+
+void initializeHostapdAndVendorHal(const std::string& hostapd_instance_name) {
+    startAndConfigureVendorHal();
+    HostapdManager hostapd_manager;
+    ASSERT_TRUE(hostapd_manager.StartHostapd());
+    getHostapd(hostapd_instance_name);
+}
+
+void stopHostapdAndVendorHal() {
+    stopHostapd();
+    stopVendorHal();
+}
+
+void startWifiFramework() {
+    toggleWifiFramework(true);
+}
+
+std::string setupApIfaceAndGetName(bool isBridged) {
+    if (HostapdAidlTestUtils::useAidlService()) {
+        return HostapdAidlTestUtils::setupApIfaceAndGetName(isBridged);
+    } else {
+        return HostapdLegacyTestUtils::setupApIfaceAndGetName(isBridged);
+    }
+}