Merge "Update IFace getFeatures/setFeature and feature names" into sc-dev
diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp
index 599f3c3..2aeee43 100644
--- a/audio/core/all-versions/default/StreamIn.cpp
+++ b/audio/core/all-versions/default/StreamIn.cpp
@@ -413,8 +413,8 @@
 
     // Create and launch the thread.
     auto tempReadThread =
-        std::make_unique<ReadThread>(&mStopReadThread, mStream, tempCommandMQ.get(),
-                                     tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get());
+            sp<ReadThread>::make(&mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(),
+                                 tempStatusMQ.get(), tempElfGroup.get());
     if (!tempReadThread->init()) {
         ALOGW("failed to start reader thread: %s", strerror(-status));
         sendError(Result::INVALID_ARGUMENTS);
@@ -430,7 +430,7 @@
     mCommandMQ = std::move(tempCommandMQ);
     mDataMQ = std::move(tempDataMQ);
     mStatusMQ = std::move(tempStatusMQ);
-    mReadThread = tempReadThread.release();
+    mReadThread = tempReadThread;
     mEfGroup = tempElfGroup.release();
 #if MAJOR_VERSION <= 6
     threadInfo.pid = getpid();
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index 5e4dd2a..6eed3da 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -398,8 +398,8 @@
 
     // Create and launch the thread.
     auto tempWriteThread =
-        std::make_unique<WriteThread>(&mStopWriteThread, mStream, tempCommandMQ.get(),
-                                      tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get());
+            sp<WriteThread>::make(&mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(),
+                                  tempStatusMQ.get(), tempElfGroup.get());
     if (!tempWriteThread->init()) {
         ALOGW("failed to start writer thread: %s", strerror(-status));
         sendError(Result::INVALID_ARGUMENTS);
@@ -415,7 +415,7 @@
     mCommandMQ = std::move(tempCommandMQ);
     mDataMQ = std::move(tempDataMQ);
     mStatusMQ = std::move(tempStatusMQ);
-    mWriteThread = tempWriteThread.release();
+    mWriteThread = tempWriteThread;
     mEfGroup = tempElfGroup.release();
 #if MAJOR_VERSION <= 6
     threadInfo.pid = getpid();
diff --git a/drm/1.2/vts/functional/drm_hal_test.cpp b/drm/1.2/vts/functional/drm_hal_test.cpp
index 0dfff26..2d1068d 100644
--- a/drm/1.2/vts/functional/drm_hal_test.cpp
+++ b/drm/1.2/vts/functional/drm_hal_test.cpp
@@ -172,6 +172,7 @@
 TEST_P(DrmHalTest, OfflineLicenseTest) {
     auto sessionId = openSession();
     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, KeyType::OFFLINE);
+    closeSession(sessionId);
 
     auto res = drmPlugin->getOfflineLicenseKeySetIds(
             [&](Status status, const hidl_vec<KeySetId>& keySetIds) {
@@ -201,8 +202,6 @@
 
     err = drmPlugin->removeOfflineLicense(keySetId);
     EXPECT_EQ(Status::BAD_VALUE, err);
-
-    closeSession(sessionId);
 }
 
 /**
@@ -212,6 +211,8 @@
     auto sessionId = openSession();
     DrmHalVTSVendorModule_V1::ContentConfiguration content = getContent(KeyType::OFFLINE);
     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, content, KeyType::OFFLINE);
+    closeSession(sessionId);
+
     drmPlugin->getOfflineLicenseState(keySetId, checkKeySetIdState<Status::OK, OfflineLicenseState::USABLE>);
 
     hidl_vec<uint8_t> keyRequest = getKeyRequest(keySetId, content, KeyType::RELEASE);
@@ -226,7 +227,6 @@
 
     provideKeyResponse(keySetId, keyResponse);
     drmPlugin->getOfflineLicenseState(keySetId, checkKeySetIdState<Status::BAD_VALUE, OfflineLicenseState::UNKNOWN>);
-    closeSession(sessionId);
 }
 
 /**
diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
index b179f35..19f5e8c 100644
--- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
@@ -15,6 +15,8 @@
  */
 
 #include <composer-vts/2.2/ReadbackVts.h>
+#include <composer-vts/2.2/RenderEngineVts.h>
+#include "renderengine/ExternalTexture.h"
 
 namespace android {
 namespace hardware {
@@ -257,10 +259,11 @@
 }
 
 TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
-                                 const std::shared_ptr<Gralloc>& gralloc, Display display,
-                                 int32_t width, int32_t height, PixelFormat format,
+                                 const std::shared_ptr<Gralloc>& gralloc,
+                                 TestRenderEngine& renderEngine, Display display, int32_t width,
+                                 int32_t height, PixelFormat format,
                                  IComposerClient::Composition composition)
-    : TestLayer{client, display} {
+    : TestLayer{client, display}, mRenderEngine(renderEngine) {
     mGralloc = gralloc;
     mComposition = composition;
     mWidth = width;
@@ -293,9 +296,11 @@
 
 LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
     LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
-    layerSettings.source.buffer.buffer =
+    layerSettings.source.buffer.buffer = std::make_shared<renderengine::ExternalTexture>(
             new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
-                              static_cast<int32_t>(mFormat), 1, mUsage, mStride);
+                              static_cast<int32_t>(mFormat), 1, mUsage, mStride),
+            mRenderEngine.getInternalRenderEngine(),
+            renderengine::ExternalTexture::Usage::READABLE);
 
     layerSettings.source.buffer.usePremultipliedAlpha =
             mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED;
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
index 3becace..f78dda2 100644
--- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -69,7 +69,9 @@
                    [](renderengine::LayerSettings& settings) -> renderengine::LayerSettings* {
                        return &settings;
                    });
-    mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, mGraphicBuffer, true,
+    auto texture = std::make_shared<renderengine::ExternalTexture>(
+            mGraphicBuffer, *mRenderEngine, renderengine::ExternalTexture::Usage::WRITEABLE);
+    mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, texture, true,
                               std::move(bufferFence), &readyFence);
     int fd = readyFence.release();
     if (fd != -1) {
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
index d5eedf1..b24e3b6 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
@@ -50,6 +50,8 @@
 static const IComposerClient::Color GREEN = {0, 0xff, 0, 0xff};
 static const IComposerClient::Color BLUE = {0, 0, 0xff, 0xff};
 
+class TestRenderEngine;
+
 class TestLayer {
   public:
     TestLayer(const std::shared_ptr<ComposerClient>& client, Display display)
@@ -110,7 +112,8 @@
   public:
     TestBufferLayer(
             const std::shared_ptr<ComposerClient>& client, const std::shared_ptr<Gralloc>& gralloc,
-            Display display, int32_t width, int32_t height, PixelFormat format,
+            TestRenderEngine& renderEngine, Display display, int32_t width, int32_t height,
+            PixelFormat format,
             IComposerClient::Composition composition = IComposerClient::Composition::DEVICE);
 
     ~TestBufferLayer();
@@ -138,6 +141,7 @@
   protected:
     IComposerClient::Composition mComposition;
     std::shared_ptr<Gralloc> mGralloc;
+    TestRenderEngine& mRenderEngine;
     int32_t mFillFence;
     const native_handle_t* mBufferHandle = nullptr;
 };
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
index f2d5f19..26027d3 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
@@ -14,9 +14,12 @@
  * limitations under the License.
  */
 
+#pragma once
+
 #include <composer-vts/2.2/ReadbackVts.h>
 #include <math/half.h>
 #include <math/vec3.h>
+#include <renderengine/ExternalTexture.h>
 #include <renderengine/RenderEngine.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/GraphicBufferAllocator.h>
@@ -51,12 +54,15 @@
     void drawLayers();
     void checkColorBuffer(std::vector<V2_2::IComposerClient::Color>& expectedColors);
 
+    renderengine::RenderEngine& getInternalRenderEngine() { return *mRenderEngine; }
+
   private:
     common::V1_1::PixelFormat mFormat;
     std::vector<renderengine::LayerSettings> mCompositionLayers;
     std::unique_ptr<renderengine::RenderEngine> mRenderEngine;
     std::vector<renderengine::LayerSettings> mRenderLayers;
     sp<GraphicBuffer> mGraphicBuffer;
+
     DisplaySettings mDisplaySettings;
 };
 
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index 1463c3b..8d52173 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -288,9 +288,9 @@
                                        {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
                                        BLUE);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
-                                                       mDisplayWidth, mDisplayHeight,
-                                                       PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
@@ -422,9 +422,9 @@
                                        {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
                                        BLUE);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
-                                                       mDisplayWidth, mDisplayHeight,
-                                                       PixelFormat::RGBA_FP16);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, PixelFormat::RGBA_FP16);
         layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
@@ -538,8 +538,8 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         auto deviceLayer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2,
-                PixelFormat::RGBA_8888);
+                mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight / 2, PixelFormat::RGBA_8888);
         std::vector<IComposerClient::Color> deviceColors(deviceLayer->mWidth *
                                                          deviceLayer->mHeight);
         ReadbackHelper::fillColorsArea(deviceColors, deviceLayer->mWidth,
@@ -575,8 +575,8 @@
         }
 
         auto clientLayer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGralloc, mPrimaryDisplay, clientWidth, clientHeight,
-                PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE);
+                mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, clientWidth,
+                clientHeight, PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE);
         IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight};
         clientLayer->setDisplayFrame(clientFrame);
         clientLayer->setZOrder(0);
@@ -657,9 +657,9 @@
         std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
-                                                       mDisplayWidth, mDisplayHeight,
-                                                       PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
@@ -805,9 +805,9 @@
                                        {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
                                        BLUE);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
-                                                       mDisplayWidth, mDisplayHeight,
-                                                       PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
@@ -957,9 +957,9 @@
         backgroundLayer->setZOrder(0);
         backgroundLayer->setColor(mBackgroundColor);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
-                                                       mDisplayWidth, mDisplayHeight,
-                                                       PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+                mDisplayHeight, PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
         layer->setZOrder(10);
         layer->setDataspace(Dataspace::UNKNOWN, mWriter);
@@ -1195,9 +1195,9 @@
         IComposerClient::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength,
                                           mSideLength};
 
-        mLayer =
-            std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
-                                              mSideLength, mSideLength, PixelFormat::RGBA_8888);
+        mLayer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, *mTestRenderEngine,
+                                                   mPrimaryDisplay, mSideLength, mSideLength,
+                                                   PixelFormat::RGBA_8888);
         mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
         mLayer->setZOrder(10);
 
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/FusedActivationFunc.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/FusedActivationFunc.aidl
index 861b6f0..df015ca 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/FusedActivationFunc.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/FusedActivationFunc.aidl
@@ -22,8 +22,20 @@
 @VintfStability
 @Backing(type="int")
 enum FusedActivationFunc {
+    /**
+     * No activation.
+     */
     NONE,
+    /**
+     * ReLU(x) = max(0, x)
+     */
     RELU,
+    /**
+     * ReLU1(x) = min(1, max(-1, x))
+     */
     RELU1,
+    /**
+     * ReLU6(x) = min(6, max(0, x))
+     */
     RELU6,
 }
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/InvalidDevice.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/InvalidDevice.h
new file mode 100644
index 0000000..e66507a
--- /dev/null
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/InvalidDevice.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/neuralnetworks/BnBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
+#include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h>
+#include <android/binder_auto_utils.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace aidl::android::hardware::neuralnetworks {
+
+class InvalidDevice : public BnDevice {
+  public:
+    static std::shared_ptr<InvalidDevice> create();
+
+    InvalidDevice(Capabilities capabilities, const NumberOfCacheFiles& numberOfCacheFiles,
+                  std::vector<Extension> extensions, DeviceType deviceType,
+                  std::string versionString);
+
+    ndk::ScopedAStatus allocate(const BufferDesc& desc,
+                                const std::vector<IPreparedModelParcel>& preparedModels,
+                                const std::vector<BufferRole>& inputRoles,
+                                const std::vector<BufferRole>& outputRoles,
+                                DeviceBuffer* deviceBuffer) override;
+    ndk::ScopedAStatus getCapabilities(Capabilities* capabilities) override;
+    ndk::ScopedAStatus getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) override;
+    ndk::ScopedAStatus getSupportedExtensions(std::vector<Extension>* extensions) override;
+    ndk::ScopedAStatus getSupportedOperations(const Model& model,
+                                              std::vector<bool>* supportedOperations) override;
+    ndk::ScopedAStatus getType(DeviceType* deviceType) override;
+    ndk::ScopedAStatus getVersionString(std::string* versionString) override;
+    ndk::ScopedAStatus prepareModel(
+            const Model& model, ExecutionPreference preference, Priority priority, int64_t deadline,
+            const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+            const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+            const std::vector<uint8_t>& token,
+            const std::shared_ptr<IPreparedModelCallback>& callback) override;
+    ndk::ScopedAStatus prepareModelFromCache(
+            int64_t deadline, const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+            const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+            const std::vector<uint8_t>& token,
+            const std::shared_ptr<IPreparedModelCallback>& callback) override;
+
+  private:
+    const Capabilities kCapabilities;
+    const NumberOfCacheFiles kNumberOfCacheFiles;
+    const std::vector<Extension> kExtensions;
+    const DeviceType kDeviceType;
+    const std::string kVersionString;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks
diff --git a/neuralnetworks/aidl/utils/src/InvalidDevice.cpp b/neuralnetworks/aidl/utils/src/InvalidDevice.cpp
new file mode 100644
index 0000000..c9d9955
--- /dev/null
+++ b/neuralnetworks/aidl/utils/src/InvalidDevice.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InvalidDevice"
+
+#include "InvalidDevice.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
+#include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h>
+#include <android/binder_auto_utils.h>
+
+#include "Conversions.h"
+#include "Utils.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace aidl::android::hardware::neuralnetworks {
+namespace {
+
+ndk::ScopedAStatus toAStatus(ErrorStatus errorStatus, const std::string& errorMessage) {
+    if (errorStatus == ErrorStatus::NONE) {
+        return ndk::ScopedAStatus::ok();
+    }
+    return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            static_cast<int32_t>(errorStatus), errorMessage.c_str());
+}
+
+}  // namespace
+
+std::shared_ptr<InvalidDevice> InvalidDevice::create() {
+    constexpr auto perf = PerformanceInfo{
+            .execTime = std::numeric_limits<float>::max(),
+            .powerUsage = std::numeric_limits<float>::max(),
+    };
+    auto capabilities = Capabilities{
+            .relaxedFloat32toFloat16PerformanceScalar = perf,
+            .relaxedFloat32toFloat16PerformanceTensor = perf,
+            .operandPerformance = {},
+            .ifPerformance = perf,
+            .whilePerformance = perf,
+    };
+    constexpr auto numberOfCacheFiles = NumberOfCacheFiles{
+            .numModelCache = 0,
+            .numDataCache = 0,
+    };
+    std::vector<Extension> extensions{};
+    constexpr auto deviceType = DeviceType::OTHER;
+    std::string versionString = "invalid";
+
+    return ndk::SharedRefBase::make<InvalidDevice>(std::move(capabilities), numberOfCacheFiles,
+                                                   std::move(extensions), deviceType,
+                                                   std::move(versionString));
+}
+
+InvalidDevice::InvalidDevice(Capabilities capabilities,
+                             const NumberOfCacheFiles& numberOfCacheFiles,
+                             std::vector<Extension> extensions, DeviceType deviceType,
+                             std::string versionString)
+    : kCapabilities(std::move(capabilities)),
+      kNumberOfCacheFiles(numberOfCacheFiles),
+      kExtensions(std::move(extensions)),
+      kDeviceType(deviceType),
+      kVersionString(std::move(versionString)) {}
+
+ndk::ScopedAStatus InvalidDevice::allocate(
+        const BufferDesc& /*desc*/, const std::vector<IPreparedModelParcel>& /*preparedModels*/,
+        const std::vector<BufferRole>& /*inputRoles*/,
+        const std::vector<BufferRole>& /*outputRoles*/, DeviceBuffer* /*deviceBuffer*/) {
+    return toAStatus(ErrorStatus::GENERAL_FAILURE, "InvalidDevice");
+}
+
+ndk::ScopedAStatus InvalidDevice::getCapabilities(Capabilities* capabilities) {
+    *capabilities = kCapabilities;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus InvalidDevice::getNumberOfCacheFilesNeeded(
+        NumberOfCacheFiles* numberOfCacheFiles) {
+    *numberOfCacheFiles = kNumberOfCacheFiles;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus InvalidDevice::getSupportedExtensions(std::vector<Extension>* extensions) {
+    *extensions = kExtensions;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus InvalidDevice::getSupportedOperations(const Model& model,
+                                                         std::vector<bool>* supportedOperations) {
+    if (const auto result = utils::validate(model); !result.ok()) {
+        return toAStatus(ErrorStatus::INVALID_ARGUMENT, result.error());
+    }
+    *supportedOperations = std::vector<bool>(model.main.operations.size(), false);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus InvalidDevice::getType(DeviceType* deviceType) {
+    *deviceType = kDeviceType;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus InvalidDevice::getVersionString(std::string* versionString) {
+    *versionString = kVersionString;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus InvalidDevice::prepareModel(
+        const Model& model, ExecutionPreference preference, Priority priority, int64_t deadline,
+        const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+        const std::vector<ndk::ScopedFileDescriptor>& dataCache, const std::vector<uint8_t>& token,
+        const std::shared_ptr<IPreparedModelCallback>& callback) {
+    if (callback.get() == nullptr) {
+        return toAStatus(ErrorStatus::INVALID_ARGUMENT,
+                         "invalid callback passed to InvalidDevice::prepareModel");
+    }
+    if (const auto result = utils::validate(model); !result.ok()) {
+        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
+        return toAStatus(ErrorStatus::INVALID_ARGUMENT, result.error());
+    }
+    if (const auto result = utils::validate(preference); !result.ok()) {
+        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
+        return toAStatus(ErrorStatus::INVALID_ARGUMENT, result.error());
+    }
+    if (const auto result = utils::validate(priority); !result.ok()) {
+        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
+        return toAStatus(ErrorStatus::INVALID_ARGUMENT, result.error());
+    }
+    if (deadline < -1) {
+        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
+        return toAStatus(ErrorStatus::INVALID_ARGUMENT,
+                         "Invalid deadline " + std::to_string(deadline));
+    }
+    if (modelCache.size() != static_cast<size_t>(kNumberOfCacheFiles.numModelCache)) {
+        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
+        return toAStatus(ErrorStatus::INVALID_ARGUMENT,
+                         "Invalid modelCache, size = " + std::to_string(modelCache.size()));
+    }
+    if (dataCache.size() != static_cast<size_t>(kNumberOfCacheFiles.numDataCache)) {
+        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
+        return toAStatus(ErrorStatus::INVALID_ARGUMENT,
+                         "Invalid modelCache, size = " + std::to_string(dataCache.size()));
+    }
+    if (token.size() != IDevice::BYTE_SIZE_OF_CACHE_TOKEN) {
+        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
+        return toAStatus(
+                ErrorStatus::INVALID_ARGUMENT,
+                "Invalid cache token, size = " + std::to_string(IDevice::BYTE_SIZE_OF_CACHE_TOKEN));
+    }
+    callback->notify(ErrorStatus::GENERAL_FAILURE, nullptr);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus InvalidDevice::prepareModelFromCache(
+        int64_t /*deadline*/, const std::vector<ndk::ScopedFileDescriptor>& /*modelCache*/,
+        const std::vector<ndk::ScopedFileDescriptor>& /*dataCache*/,
+        const std::vector<uint8_t>& /*token*/,
+        const std::shared_ptr<IPreparedModelCallback>& callback) {
+    callback->notify(ErrorStatus::GENERAL_FAILURE, nullptr);
+    return toAStatus(ErrorStatus::GENERAL_FAILURE, "InvalidDevice");
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks
diff --git a/neuralnetworks/aidl/utils/src/Service.cpp b/neuralnetworks/aidl/utils/src/Service.cpp
index 511de55..ac182a2 100644
--- a/neuralnetworks/aidl/utils/src/Service.cpp
+++ b/neuralnetworks/aidl/utils/src/Service.cpp
@@ -16,6 +16,7 @@
 
 #include "Service.h"
 
+#include <AndroidVersionUtil.h>
 #include <android/binder_auto_utils.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
@@ -35,13 +36,23 @@
     hal::utils::ResilientDevice::Factory makeDevice =
             [instanceName,
              name = std::move(fullName)](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
-        const auto& getService =
-                blocking ? AServiceManager_getService : AServiceManager_checkService;
+        std::add_pointer_t<AIBinder*(const char*)> getService;
+        if (blocking) {
+            if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
+                getService = AServiceManager_waitForService;
+            } else {
+                getService = AServiceManager_getService;
+            }
+        } else {
+            getService = AServiceManager_checkService;
+        }
+
         auto service = IDevice::fromBinder(ndk::SpAIBinder(getService(name.c_str())));
         if (service == nullptr) {
-            return NN_ERROR() << (blocking ? "AServiceManager_getService"
-                                           : "AServiceManager_checkService")
-                              << " returned nullptr";
+            return NN_ERROR()
+                   << (blocking ? "AServiceManager_waitForService (or AServiceManager_getService)"
+                                : "AServiceManager_checkService")
+                   << " returned nullptr";
         }
         ABinderProcess_startThreadPool();
         return Device::create(instanceName, std::move(service));
diff --git a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp
index 0c3a196..ee7cf89 100644
--- a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp
@@ -94,7 +94,7 @@
 }
 
 static NamedDevice makeNamedDevice(const std::string& name) {
-    ndk::SpAIBinder binder(AServiceManager_getService(name.c_str()));
+    ndk::SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
     return {name, IDevice::fromBinder(binder)};
 }
 
diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal
index 9788345..05a7585 100644
--- a/radio/1.6/IRadioIndication.hal
+++ b/radio/1.6/IRadioIndication.hal
@@ -107,7 +107,7 @@
     /**
      * Indicates physical channel configurations.
      *
-     * An empty configs list indicates that the radio is in idle mode.
+     * An empty configs list shall be returned when the radio is in idle mode (i.e. RRC idle).
      *
      * @param type Type of radio indication
      * @param configs Vector of PhysicalChannelConfigs
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index 33fe94f..89ededa 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -232,6 +232,7 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INVALID_STATE
      */
     oneway setNrDualConnectivityStateResponse(RadioResponseInfo info);
 
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 2f08e83..91fdf9d 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -175,7 +175,7 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
-    if (getRadioHalCapabilities().modemReducedFeatureSet1) {
+    if (getRadioHalCapabilities()) {
         ASSERT_TRUE(CheckAnyOfErrors(
                 radioRsp_v1_6->rspInfo.error,
                 {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}));
@@ -383,7 +383,7 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
-    if (getRadioHalCapabilities().modemReducedFeatureSet1) {
+    if (getRadioHalCapabilities()) {
         ASSERT_TRUE(CheckAnyOfErrors(
                 radioRsp_v1_6->rspInfo.error,
                 {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}));
@@ -392,6 +392,7 @@
                 CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
                                  {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
                                   ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR,
+                                  ::android::hardware::radio::V1_6::RadioError::INVALID_STATE,
                                   ::android::hardware::radio::V1_6::RadioError::NONE}));
     }
 }
@@ -408,7 +409,7 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
-    if (getRadioHalCapabilities().modemReducedFeatureSet1) {
+    if (getRadioHalCapabilities()) {
         ASSERT_TRUE(CheckAnyOfErrors(
                 radioRsp_v1_6->rspInfo.error,
                 {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}));
@@ -434,7 +435,7 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
-    if (getRadioHalCapabilities().modemReducedFeatureSet1) {
+    if (getRadioHalCapabilities()) {
         ASSERT_TRUE(CheckAnyOfErrors(
                 radioRsp_v1_6->rspInfo.error,
                 {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}));
@@ -454,7 +455,7 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
-    if (getRadioHalCapabilities().modemReducedFeatureSet1) {
+    if (getRadioHalCapabilities()) {
         ASSERT_TRUE(CheckAnyOfErrors(
                 radioRsp_v1_6->rspInfo.error,
                 {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}));
@@ -474,7 +475,7 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
-    if (getRadioHalCapabilities().modemReducedFeatureSet1) {
+    if (getRadioHalCapabilities()) {
         ASSERT_TRUE(CheckAnyOfErrors(
                 radioRsp_v1_6->rspInfo.error,
                 {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}));
@@ -493,7 +494,7 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
-    if (getRadioHalCapabilities().modemReducedFeatureSet1) {
+    if (getRadioHalCapabilities()) {
         ASSERT_TRUE(CheckAnyOfErrors(
                 radioRsp_v1_6->rspInfo.error,
                 {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}));
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
index 6255f66..5d514a0 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
@@ -86,16 +86,14 @@
  * disabled.
  * <p/>
  * Typical usage within VTS:
- * if (getRadioHalCapabilities().modemReducedFeatureSet) return;
+ * if (getRadioHalCapabilities()) return;
  */
-HalDeviceCapabilities RadioHidlTest_v1_6::getRadioHalCapabilities() {
+bool RadioHidlTest_v1_6::getRadioHalCapabilities() {
     sp<::android::hardware::radio::config::V1_3::IRadioConfig> radioConfig_v1_3 =
             ::android::hardware::radio::config::V1_3::IRadioConfig::getService();
     if (radioConfig_v1_3.get() == nullptr) {
         // If v1_3 isn't present, the values are initialized to false
-        HalDeviceCapabilities radioHalCapabilities;
-        memset(&radioHalCapabilities, 0, sizeof(radioHalCapabilities));
-        return radioHalCapabilities;
+        return false;
     } else {
         // Get radioHalDeviceCapabilities from the radio config
         sp<RadioConfigResponse> radioConfigRsp = new (std::nothrow) RadioConfigResponse(*this);
@@ -104,6 +102,6 @@
 
         radioConfig_v1_3->getHalDeviceCapabilities(serial);
         EXPECT_EQ(std::cv_status::no_timeout, wait());
-        return radioConfigRsp->halDeviceCapabilities;
+        return radioConfigRsp->modemReducedFeatureSet1;
     }
 }
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 4fc17e5..114091a 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -38,14 +38,12 @@
 using namespace ::android::hardware::radio::V1_2;
 using namespace ::android::hardware::radio::V1_1;
 using namespace ::android::hardware::radio::V1_0;
-using namespace ::android::hardware::radio::config::V1_3;
 
 using ::android::sp;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities;
 
 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
@@ -1115,7 +1113,7 @@
   public:
     virtual void SetUp() override;
 
-    HalDeviceCapabilities getRadioHalCapabilities();
+    bool getRadioHalCapabilities();
 
     /* radio service handle */
     sp<::android::hardware::radio::V1_6::IRadio> radio_v1_6;
diff --git a/radio/config/1.3/Android.bp b/radio/config/1.3/Android.bp
index cc5944d..dc0d82c 100644
--- a/radio/config/1.3/Android.bp
+++ b/radio/config/1.3/Android.bp
@@ -13,7 +13,6 @@
     name: "android.hardware.radio.config@1.3",
     root: "android.hardware",
     srcs: [
-        "types.hal",
         "IRadioConfig.hal",
         "IRadioConfigResponse.hal",
     ],
diff --git a/radio/config/1.3/IRadioConfigResponse.hal b/radio/config/1.3/IRadioConfigResponse.hal
index 863754f..15eefed 100644
--- a/radio/config/1.3/IRadioConfigResponse.hal
+++ b/radio/config/1.3/IRadioConfigResponse.hal
@@ -18,7 +18,6 @@
 
 import android.hardware.radio@1.6::RadioResponseInfo;
 import @1.2::IRadioConfigResponse;
-import HalDeviceCapabilities;
 
 /**
  * Interface declaring response functions to solicited radio config requests.
@@ -26,8 +25,18 @@
 interface IRadioConfigResponse extends @1.2::IRadioConfigResponse {
     /**
      * @param info Response info struct containing response type, serial no. and error
-     * @param capabilities Capabilities struct containing the capabilities of the
-     * device related to the Radio HAL
+     * @param modemReducedFeatureSet1 True indicates that the modem does NOT support the following
+     *        features.
+     *        - Providing either
+     *          android.hardware.radio@1.6::LinkCapacityEstimate:secondaryDownlinkCapacityKbps
+     *          or android.hardware.radio@1.6::LinkCapacityEstimate:secondaryUplinkCapacityKbps
+     *          when given from
+     *          android.hardware.radio@1.6::RadioIndication:currentLinkCapacityEstimate
+     *        - Calling android.hardware.radio@1.6::IRadio.setNrDualConnectivityState
+     *          or querying android.hardware.radio@1.6::IRadio.isNrDualConnectivityEnabled
+     *        - Requesting android.hardware.radio@1.6::IRadio.setDataThrottling()
+     *        - Providing android.hardware.radio@1.6::SlicingConfig through
+     *          android.hardware.radio@1.6::getSlicingConfig()
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -35,5 +44,5 @@
      *   RadioError:INTERNAL_ERR
      */
     oneway getHalDeviceCapabilitiesResponse(RadioResponseInfo info,
-        HalDeviceCapabilities capabilities);
+        bool modemReducedFeatureSet1);
 };
diff --git a/radio/config/1.3/types.hal b/radio/config/1.3/types.hal
deleted file mode 100644
index 8667f0a..0000000
--- a/radio/config/1.3/types.hal
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.radio.config@1.3;
-
-/**
- * Contains the device capabilities with respect to the Radio HAL.
- */
-struct HalDeviceCapabilities {
-  /**
-   * True indicates that the modem does NOT support the following features:
-   * <ul>
-   * <li>Providing either
-   * android.hardware.radio@1.6::LinkCapacityEstimate:secondaryDownlinkCapacityKbps
-   * or android.hardware.radio@1.6::LinkCapacityEstimate:secondaryUplinkCapacityKbps
-   * when given from android.hardware.radio@1.6::RadioIndication:currentLinkCapacityEstimate
-   * </li>
-   * <li> calling android.hardware.radio@1.6::IRadio.setNrDualConnectivityState
-   * or querying android.hardware.radio@1.6::IRadio.isNrDualConnectivityEnabled
-   * </li>
-   * <li>Requesting android.hardware.radio@1.6::IRadio.setDataThrottling()
-   * </li>
-   * <li>Providing android.hardware.radio@1.6::SlicingConfig through
-   * android.hardware.radio@1.6::getSlicingConfig()
-   * </li>
-   * </ul>
-   */
-  bool modemReducedFeatureSet1;
-};
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
index 50038eb..7235798 100644
--- a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
@@ -29,7 +29,6 @@
 #include <android/hardware/radio/config/1.2/types.h>
 #include <android/hardware/radio/config/1.3/IRadioConfig.h>
 #include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
-#include <android/hardware/radio/config/1.3/types.h>
 #include <gtest/gtest.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
@@ -48,7 +47,6 @@
 using ::android::hardware::radio::config::V1_1::PhoneCapability;
 using ::android::hardware::radio::config::V1_2::IRadioConfigIndication;
 using ::android::hardware::radio::config::V1_2::SimSlotStatus;
-using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities;
 using ::android::hardware::radio::config::V1_3::IRadioConfig;
 using ::android::hardware::radio::config::V1_3::IRadioConfigResponse;
 using ::android::hardware::radio::V1_0::RadioResponseInfo;
@@ -65,7 +63,7 @@
   public:
     RadioResponseInfo rspInfo;
     PhoneCapability phoneCap;
-    HalDeviceCapabilities halDeviceCapabilities;
+    bool modemReducedFeatureSet1;
 
     RadioConfigResponse(RadioResponseWaiter& parent);
     virtual ~RadioConfigResponse() = default;
@@ -93,7 +91,7 @@
 
     Return<void> getHalDeviceCapabilitiesResponse(
             const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
-            const HalDeviceCapabilities& halDeviceCapabilities);
+            bool modemReducedFeatureSet1);
 };
 
 /* Callback class for radio config indication */
diff --git a/radio/config/1.3/vts/functional/radio_config_response.cpp b/radio/config/1.3/vts/functional/radio_config_response.cpp
index 5501ae2..6188733 100644
--- a/radio/config/1.3/vts/functional/radio_config_response.cpp
+++ b/radio/config/1.3/vts/functional/radio_config_response.cpp
@@ -65,8 +65,8 @@
 
 Return<void> RadioConfigResponse::getHalDeviceCapabilitiesResponse(
         const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
-        const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& capabilities) {
-    halDeviceCapabilities = capabilities;
+        bool modemReducedFeatures) {
+    modemReducedFeatureSet1 = modemReducedFeatures;
     parent.notify(info.serial);
     return Void();
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
index f3c5477..c2e21b6 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -60,29 +60,36 @@
      * `attestationKey` parameter of `generateKey()`, `importKey()` or `importWrappedKey()`), and in
      * the non-attestaion case, whether the key can self-sign.
      *
-     * 1.  Attestation with factory key.  If Tag::ATTESTATION_CHALLENGE is provided and the
-     *     `attestationKey` parameter on the generate/import call is null, the returned certificate
-     *     chain must contain an attestation certificate signed with a factory-provisioned
-     *     attestation key, and the full certificate chain for that factory-provisioned attestation
-     *     key.
+     * 1.  Asymmetric key attestation with factory key.  If Tag::ATTESTATION_CHALLENGE is provided
+     *     and the `attestationKey` parameter on the generate/import call is null, the returned
+     *     certificate chain must contain an attestation certificate signed with a factory-
+     *     provisioned attestation key, and the full certificate chain for that factory-provisioned
+     *     attestation key.  Tag::ATTESTATION_APPLICATION_ID must also be provided when the
+     *     ATTESTATION_CHALLENGE is provided, otherwise ATTESTATION_APPLICATION_ID_MISSING will be
+     *     returned.
      *
-     * 2.  Attestation with caller-provided key.  If Tag::ATTESTATION_CHALLENGE is provided and the
-     *     `attestationKey` parameter on the generat/import call is non-null and contains the key
-     *     blob of a key with KeyPurpose::ATTEST_KEY, the returned certificate chain must contain
-     *     only an attestation certificate signed with the specified key.  The caller must know the
-     *     certificate chain for the provided key.
+     * 2.  Asymmetric key attestation with caller-provided key.  If Tag::ATTESTATION_CHALLENGE is
+     *     provided and the `attestationKey` parameter on the generat/import call is non-null and
+     *     contains the key blob of a key with KeyPurpose::ATTEST_KEY, the returned certificate
+     *     chain must contain only an attestation certificate signed with the specified key.  The
+     *     caller must know the certificate chain for the provided key.  Tag::
+     *     ATTESTATION_APPLICATION_ID must also be provided when the ATTESTATION_CHALLENGE is
+     *     provided, otherwise ATTESTATION_APPLICATION_ID_MISSING will be returned.
      *
-     * 3.  Non-attestation with signing key.  If Tag::ATTESTATION_CHALLENGE is not provided and the
-     *     generated/imported key has KeyPurpose::SIGN, then the returned certificate chain must
-     *     contain only a single self-signed certificate with no attestation extension.
+     * 3.  Asymmetric key non-attestation with signing key.  If Tag::ATTESTATION_CHALLENGE is not
+     *     provided and the generated/imported key has KeyPurpose::SIGN, then the returned
+     *     certificate chain must contain only a single self-signed certificate with no attestation
+     *     extension.  Tag::ATTESTATION_APPLICATION_ID will be ignored if provided.
      *
-     * 4.  Non-attestation with non-signing key.  If TAG::ATTESTATION_CHALLENGE is not provided and
-     *     the generated/imported key does not have KeyPurpose::SIGN, then the returned certificate
-     *     chain must contain only a single certificate with an empty signature and no attestation
-     *     extension.
+     * 4.  Asymmetric key non-attestation with non-signing key.  If TAG::ATTESTATION_CHALLENGE is
+     *     not provided and the generated/imported key does not have KeyPurpose::SIGN, then the
+     *     returned certificate chain must contain only a single certificate with an empty signature
+     *     and no attestation extension.  Tag::ATTESTATION_APPLICATION_ID will be ignored if
+     *     provided.
      *
-     * 5.  Symmetric key.  If the generated/imported key is symmetric, the certificate chain must be
-     *     empty.
+     * 5.  Symmetric key.  If the generated/imported key is symmetric, the certificate chain must
+     *     return empty, any Tag::ATTESTATION_CHALLENGE or Tag::ATTESTATION_APPLICATION_ID inputs,
+     *     if provided, are ignored.
      */
     Certificate[] certificateChain;
 }
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index d5308dc..2d28845 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -137,6 +137,54 @@
                 "d5f33645e8ed8b4a1cb3cc4a1d67987399f2a09f5b3fb68c88d5e5d90ac3"
                 "3492d6");
 
+/*
+ * DER-encoded PKCS#8 format RSA key. Generated using:
+ *
+ * openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -outform der | hexdump -e '30/1  "%02X" "\n"'
+ */
+string rsa_2048_key =
+        hex2str("308204BD020100300D06092A864886F70D0101010500048204A7308204A3"
+                "0201000282010100BEBC342B56D443B1299F9A6A7056E80A897E318476A5"
+                "A18029E63B2ED739A61791D339F58DC763D9D14911F2EDEC383DEE11F631"
+                "9B44510E7A3ECD9B79B97382E49500ACF8117DC89CAF0E621F77756554A2"
+                "FD4664BFE7AB8B59AB48340DBFA27B93B5A81F6ECDEB02D0759307128DF3"
+                "E3BAD4055C8B840216DFAA5700670E6C5126F0962FCB70FF308F25049164"
+                "CCF76CC2DA66A7DD9A81A714C2809D69186133D29D84568E892B6FFBF319"
+                "9BDB14383EE224407F190358F111A949552ABA6714227D1BD7F6B20DD0CB"
+                "88F9467B719339F33BFF35B3870B3F62204E4286B0948EA348B524544B5F"
+                "9838F29EE643B079EEF8A713B220D7806924CDF7295070C5020301000102"
+                "82010069F377F35F2F584EF075353CCD1CA99738DB3DBC7C7FF35F9366CE"
+                "176DFD1B135AB10030344ABF5FBECF1D4659FDEF1C0FC430834BE1BE3911"
+                "951377BB3D563A2EA9CA8F4AD9C48A8CE6FD516A735C662686C7B4B3C09A"
+                "7B8354133E6F93F790D59EAEB92E84C9A4339302CCE28FDF04CCCAFA7DE3"
+                "F3A827D4F6F7D38E68B0EC6AB706645BF074A4E4090D06FB163124365FD5"
+                "EE7A20D350E9958CC30D91326E1B292E9EF5DB408EC42DAF737D20149704"
+                "D0A678A0FB5B5446863B099228A352D604BA8091A164D01D5AB05397C71E"
+                "AD20BE2A08FC528FE442817809C787FEE4AB97F97B9130D022153EDC6EB6"
+                "CBE7B0F8E3473F2E901209B5DB10F93604DB0102818100E83C0998214941"
+                "EA4F9293F1B77E2E99E6CF305FAF358238E126124FEAF2EB9724B2EA7B78"
+                "E6032343821A80E55D1D88FB12D220C3F41A56142FEC85796D1917F1E8C7"
+                "74F142B67D3D6E7B7E6B4383E94DB5929089DBB346D5BDAB40CC2D96EE04"
+                "09475E175C63BF78CFD744136740838127EA723FF3FE7FA368C1311B4A4E"
+                "0502818100D240FCC0F5D7715CDE21CB2DC86EA146132EA3B06F61FF2AF5"
+                "4BF38473F59DADCCE32B5F4CC32DD0BA6F509347B4B5B1B58C39F95E4798"
+                "CCBB43E83D0119ACF532F359CA743C85199F0286610E200997D731291717"
+                "9AC9B67558773212EC961E8BCE7A3CC809BC5486A96E4B0E6AF394D94E06"
+                "6A0900B7B70E82A44FB30053C102818100AD15DA1CBD6A492B66851BA8C3"
+                "16D38AB700E2CFDDD926A658003513C54BAA152B30021D667D20078F500F"
+                "8AD3E7F3945D74A891ED1A28EAD0FEEAEC8C14A8E834CF46A13D1378C99D"
+                "18940823CFDD27EC5810D59339E0C34198AC638E09C87CBB1B634A9864AE"
+                "9F4D5EB2D53514F67B4CAEC048C8AB849A02E397618F3271350281801FA2"
+                "C1A5331880A92D8F3E281C617108BF38244F16E352E69ED417C7153F9EC3"
+                "18F211839C643DCF8B4DD67CE2AC312E95178D5D952F06B1BF779F491692"
+                "4B70F582A23F11304E02A5E7565AE22A35E74FECC8B6FDC93F92A1A37703"
+                "E4CF0E63783BD02EB716A7ECBBFA606B10B74D01579522E7EF84D91FC522"
+                "292108D902C1028180796FE3825F9DCC85DF22D58690065D93898ACD65C0"
+                "87BEA8DA3A63BF4549B795E2CD0E3BE08CDEBD9FCF1720D9CDC5070D74F4"
+                "0DED8E1102C52152A31B6165F83A6722AECFCC35A493D7634664B888A08D"
+                "3EB034F12EA28BFEE346E205D334827F778B16ED40872BD29FCB36536B6E"
+                "93FFB06778696B4A9D81BB0A9423E63DE5");
+
 string ec_256_key =
         hex2str("308187020100301306072a8648ce3d020106082a8648ce3d030107046d30"
                 "6b0201010420737c2ecd7b8d1940bf2930aa9b4ed3ff941eed09366bc032"
@@ -1811,16 +1859,27 @@
  * Verifies that importing and using an RSA key pair works correctly.
  */
 TEST_P(ImportKeyTest, RsaSuccess) {
+    uint32_t key_size;
+    string key;
+
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        key_size = 2048;
+        key = rsa_2048_key;
+    } else {
+        key_size = 1024;
+        key = rsa_key;
+    }
+
     ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
                                                .Authorization(TAG_NO_AUTH_REQUIRED)
-                                               .RsaSigningKey(1024, 65537)
+                                               .RsaSigningKey(key_size, 65537)
                                                .Digest(Digest::SHA_2_256)
                                                .Padding(PaddingMode::RSA_PSS)
                                                .SetDefaultValidity(),
-                                       KeyFormat::PKCS8, rsa_key));
+                                       KeyFormat::PKCS8, key));
 
     CheckCryptoParam(TAG_ALGORITHM, Algorithm::RSA);
-    CheckCryptoParam(TAG_KEY_SIZE, 1024U);
+    CheckCryptoParam(TAG_KEY_SIZE, key_size);
     CheckCryptoParam(TAG_RSA_PUBLIC_EXPONENT, 65537U);
     CheckCryptoParam(TAG_DIGEST, Digest::SHA_2_256);
     CheckCryptoParam(TAG_PADDING, PaddingMode::RSA_PSS);
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index a9d1ed5..4d03ebf 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -553,8 +553,6 @@
 }
 
 TEST_P(VibratorAidl, ComposeCallback) {
-    constexpr std::chrono::milliseconds allowedLatency{10};
-
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
         std::vector<CompositePrimitive> supported;
 
@@ -586,17 +584,16 @@
                 << toString(primitive);
             duration = std::chrono::milliseconds(durationMs);
 
+            start = high_resolution_clock::now();
             EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
                 << toString(primitive);
-            start = high_resolution_clock::now();
 
-            EXPECT_EQ(completionFuture.wait_for(duration + allowedLatency), std::future_status::ready)
+            EXPECT_EQ(completionFuture.wait_for(duration * 2), std::future_status::ready)
                 << toString(primitive);
             end = high_resolution_clock::now();
 
             elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
-            EXPECT_LE(elapsed.count(), (duration + allowedLatency).count()) << toString(primitive);
-            EXPECT_GE(elapsed.count(), (duration - allowedLatency).count()) << toString(primitive);
+            EXPECT_GE(elapsed.count(), duration.count()) << toString(primitive);
         }
     }
 }
diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal
index e199850..8d7a36e 100644
--- a/wifi/1.5/IWifiChip.hal
+++ b/wifi/1.5/IWifiChip.hal
@@ -47,6 +47,15 @@
      *   - 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, the must 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).
      */
     enum MultiStaUseCase : uint8_t {
         /**
@@ -100,11 +109,14 @@
     /**
      * Invoked to indicate that the provided iface is the primary STA iface when there are more
      * than 1 STA iface concurrently active.
-     * Note: 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.
+     * 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.
      * @return status WifiStatus of the operation.