Merge "NNAPI VTS: decouple 1.2 tests from 1.3 types" into rvc-dev
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
index a2f4116..8ef2b43 100644
--- a/audio/core/all-versions/vts/functional/ConfigHelper.h
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -40,7 +40,7 @@
             return devs.getDevice(AUDIO_DEVICE_IN_BUILTIN_MIC, {}, AUDIO_FORMAT_DEFAULT);
         };
         auto primaryMic = getMic(policyConfig.getPrimaryModule()->getDeclaredDevices());
-        auto availableMic = getMic(policyConfig.getAvailableInputDevices());
+        auto availableMic = getMic(policyConfig.getInputDevices());
 
         return primaryMic != nullptr && primaryMic->equals(availableMic);
     }
diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
index cde8048..368a6d4 100644
--- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
+++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
@@ -38,16 +38,15 @@
 
 #include <hidl/HidlTransportSupport.h>
 #include <hwbinder/ProcessState.h>
-#include <log/log.h>
 #include <utils/Errors.h>
 #include <utils/StrongPointer.h>
 
-#include <android/log.h>
 #include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
 #include <android/hardware/automotive/evs/1.1/IEvsCameraStream.h>
 #include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
 #include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android-base/logging.h>
 #include <system/camera_metadata.h>
 #include <ui/DisplayConfig.h>
 #include <ui/DisplayState.h>
@@ -98,18 +97,19 @@
         std::string service_name = GetParam();
         pEnumerator = IEvsEnumerator::getService(service_name);
         ASSERT_NE(pEnumerator.get(), nullptr);
+        LOG(INFO) << "Test target service: " << service_name;
 
         mIsHwModule = pEnumerator->isHardware();
     }
 
     virtual void TearDown() override {
         // Attempt to close any active camera
-        for (auto &&c : activeCameras) {
-            sp<IEvsCamera_1_1> cam = c.promote();
+        for (auto &&cam : activeCameras) {
             if (cam != nullptr) {
                 pEnumerator->closeCamera(cam);
             }
         }
+        activeCameras.clear();
     }
 
 protected:
@@ -120,11 +120,12 @@
         // Get the camera list
         pEnumerator->getCameraList_1_1(
             [this](hidl_vec <CameraDesc> cameraList) {
-                ALOGI("Camera list callback received %zu cameras",
-                      cameraList.size());
+                LOG(INFO) << "Camera list callback received "
+                          << cameraList.size()
+                          << " cameras";
                 cameraInfo.reserve(cameraList.size());
                 for (auto&& cam: cameraList) {
-                    ALOGI("Found camera %s", cam.v1.cameraId.c_str());
+                    LOG(INFO) << "Found camera " << cam.v1.cameraId;
                     cameraInfo.push_back(cam);
                 }
             }
@@ -137,10 +138,12 @@
 
         // Get the ultrasonics array list
         pEnumerator->getUltrasonicsArrayList([this](hidl_vec<UltrasonicsArrayDesc> ultraList) {
-            ALOGI("Ultrasonics array list callback received %zu arrays", ultraList.size());
+            LOG(INFO) << "Ultrasonics array list callback received "
+                      << ultraList.size()
+                      << " arrays";
             ultrasonicsArraysInfo.reserve(ultraList.size());
             for (auto&& ultraArray : ultraList) {
-                ALOGI("Found ultrasonics array %s", ultraArray.ultrasonicsArrayId.c_str());
+                LOG(INFO) << "Found ultrasonics array " << ultraArray.ultrasonicsArrayId;
                 ultrasonicsArraysInfo.push_back(ultraArray);
             }
         });
@@ -195,7 +198,7 @@
         if (!flag) {
             // EVS assumes that the device w/o a valid metadata is a physical
             // device.
-            ALOGI("%s is not a logical camera device.", id.c_str());
+            LOG(INFO) << id << " is not a logical camera device.";
             physicalCameras.emplace(id);
             return physicalCameras;
         }
@@ -205,7 +208,9 @@
         int rc = find_camera_metadata_ro_entry(metadata,
                                                ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS,
                                                &entry);
-        ALOGE_IF(rc, "No physical camera ID is found for a logical camera device");
+        if (rc != 0) {
+            LOG(ERROR) << "No physical camera ID is found for a logical camera device";
+        }
 
         const uint8_t *ids = entry.data.u8;
         size_t start = 0;
@@ -219,7 +224,10 @@
             }
         }
 
-        ALOGI("%s consists of %d physical camera devices.", id.c_str(), (int)physicalCameras.size());
+        LOG(INFO) << id
+                  << " consists of "
+                  << physicalCameras.size()
+                  << " physical camera devices";
         return physicalCameras;
     }
 
@@ -228,7 +236,7 @@
     std::vector<CameraDesc>         cameraInfo;    // Empty unless/until loadCameraList() is called
     bool                            mIsHwModule;   // boolean to tell current module under testing
                                                    // is HW module implementation.
-    std::deque<wp<IEvsCamera_1_1>>  activeCameras; // A list of active camera handles that are
+    std::deque<sp<IEvsCamera_1_1>>  activeCameras; // A list of active camera handles that are
                                                    // needed to be cleaned up.
     std::vector<UltrasonicsArrayDesc>
             ultrasonicsArraysInfo;                           // Empty unless/until
@@ -247,7 +255,7 @@
  * call to closeCamera.  Then repeats the test to ensure all cameras can be reopened.
  */
 TEST_P(EvsHidlTest, CameraOpenClean) {
-    ALOGI("Starting CameraOpenClean test");
+    LOG(INFO) << "Starting CameraOpenClean test";
 
     // Get the camera list
     loadCameraList();
@@ -261,15 +269,12 @@
         bool isLogicalCam = false;
         auto devices = getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
         if (mIsHwModule && isLogicalCam) {
-            ALOGI("Skip a logical device %s for HW module", cam.v1.cameraId.c_str());
+            LOG(INFO) << "Skip a logical device, " << cam.v1.cameraId << " for HW target.";
             continue;
         }
 
         for (int pass = 0; pass < 2; pass++) {
-            activeCameras.clear();
-            sp<IEvsCamera_1_1> pCam =
-                IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
-                .withDefault(nullptr);
+            sp<IEvsCamera_1_1> pCam = pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg);
             ASSERT_NE(pCam, nullptr);
 
             for (auto&& devName : devices) {
@@ -286,7 +291,7 @@
 
             // Verify that this camera self-identifies correctly
             pCam->getCameraInfo_1_1([&cam](CameraDesc desc) {
-                                        ALOGD("Found camera %s", desc.v1.cameraId.c_str());
+                                        LOG(DEBUG) << "Found camera " << desc.v1.cameraId;
                                         EXPECT_EQ(cam.v1.cameraId, desc.v1.cameraId);
                                     }
             );
@@ -295,15 +300,16 @@
             const auto id = 0xFFFFFFFF; // meaningless id
             hidl_vec<uint8_t> values;
             auto err = pCam->setExtendedInfo_1_1(id, values);
-            ASSERT_EQ(EvsResult::INVALID_ARG, err);
+            ASSERT_NE(EvsResult::INVALID_ARG, err);
 
             pCam->getExtendedInfo_1_1(id, [](const auto& result, const auto& data) {
-                ASSERT_EQ(EvsResult::INVALID_ARG, result);
+                ASSERT_NE(EvsResult::INVALID_ARG, result);
                 ASSERT_EQ(0, data.size());
             });
 
             // Explicitly close the camera so resources are released right away
             pEnumerator->closeCamera(pCam);
+            activeCameras.clear();
         }
     }
 }
@@ -316,7 +322,7 @@
  * the system to be tolerant of shutdown/restart race conditions.
  */
 TEST_P(EvsHidlTest, CameraOpenAggressive) {
-    ALOGI("Starting CameraOpenAggressive test");
+    LOG(INFO) << "Starting CameraOpenAggressive test";
 
     // Get the camera list
     loadCameraList();
@@ -330,7 +336,7 @@
         bool isLogicalCam = false;
         getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
         if (mIsHwModule && isLogicalCam) {
-            ALOGI("Skip a logical device %s for HW module", cam.v1.cameraId.c_str());
+            LOG(INFO) << "Skip a logical device, " << cam.v1.cameraId << " for HW target.";
             continue;
         }
 
@@ -345,7 +351,7 @@
 
         // Verify that this camera self-identifies correctly
         pCam->getCameraInfo_1_1([&cam](CameraDesc desc) {
-                                    ALOGD("Found camera %s", desc.v1.cameraId.c_str());
+                                    LOG(DEBUG) << "Found camera " << desc.v1.cameraId;
                                     EXPECT_EQ(cam.v1.cameraId, desc.v1.cameraId);
                                 }
         );
@@ -371,16 +377,18 @@
 
         // Close the superceded camera
         pEnumerator->closeCamera(pCam);
+        activeCameras.pop_front();
 
         // Verify that the second camera instance self-identifies correctly
         pCam2->getCameraInfo_1_1([&cam](CameraDesc desc) {
-                                     ALOGD("Found camera %s", desc.v1.cameraId.c_str());
+                                     LOG(DEBUG) << "Found camera " << desc.v1.cameraId;
                                      EXPECT_EQ(cam.v1.cameraId, desc.v1.cameraId);
                                  }
         );
 
         // Close the second camera instance
         pEnumerator->closeCamera(pCam2);
+        activeCameras.pop_front();
     }
 
     // Sleep here to ensure the destructor cleanup has time to run so we don't break follow on tests
@@ -393,7 +401,7 @@
  * Measure and qualify the stream start up time and streaming frame rate of each reported camera
  */
 TEST_P(EvsHidlTest, CameraStreamPerformance) {
-    ALOGI("Starting CameraStreamPerformance test");
+    LOG(INFO) << "Starting CameraStreamPerformance test";
 
     // Get the camera list
     loadCameraList();
@@ -407,11 +415,10 @@
         bool isLogicalCam = false;
         auto devices = getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
         if (mIsHwModule && isLogicalCam) {
-            ALOGI("Skip a logical device %s", cam.v1.cameraId.c_str());
+            LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
             continue;
         }
 
-        activeCameras.clear();
         sp<IEvsCamera_1_1> pCam =
             IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
             .withDefault(nullptr);
@@ -444,8 +451,10 @@
                   kMaxStreamStartMilliseconds * devices.size());
         printf("%s: Measured time to first frame %0.2f ms\n",
                cam.v1.cameraId.c_str(), timeToFirstFrame * kNanoToMilliseconds);
-        ALOGI("%s: Measured time to first frame %0.2f ms",
-              cam.v1.cameraId.c_str(), timeToFirstFrame * kNanoToMilliseconds);
+        LOG(INFO) << cam.v1.cameraId
+                  << ": Measured time to first frame "
+                  << std::scientific << timeToFirstFrame * kNanoToMilliseconds
+                  << " ms.";
 
         // Check aspect ratio
         unsigned width = 0, height = 0;
@@ -468,11 +477,14 @@
         nsecs_t runTime = end - firstFrame;
         float framesPerSecond = framesReceived / (runTime * kNanoToSeconds);
         printf("Measured camera rate %3.2f fps\n", framesPerSecond);
-        ALOGI("Measured camera rate %3.2f fps", framesPerSecond);
+        LOG(INFO) << "Measured camera rate "
+                  << std::scientific << framesPerSecond
+                  << " fps.";
         EXPECT_GE(framesPerSecond, kMinimumFramesPerSecond);
 
         // Explicitly release the camera
         pEnumerator->closeCamera(pCam);
+        activeCameras.clear();
     }
 }
 
@@ -483,7 +495,7 @@
  * than one frame time.  The camera must cleanly skip frames until the client is ready again.
  */
 TEST_P(EvsHidlTest, CameraStreamBuffering) {
-    ALOGI("Starting CameraStreamBuffering test");
+    LOG(INFO) << "Starting CameraStreamBuffering test";
 
     // Arbitrary constant (should be > 1 and less than crazy)
     static const unsigned int kBuffersToHold = 6;
@@ -500,11 +512,10 @@
         bool isLogicalCam = false;
         getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
         if (mIsHwModule && isLogicalCam) {
-            ALOGI("Skip a logical device %s for HW module", cam.v1.cameraId.c_str());
+            LOG(INFO) << "Skip a logical device " << cam.v1.cameraId << " for HW target.";
             continue;
         }
 
-        activeCameras.clear();
         sp<IEvsCamera_1_1> pCam =
             IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
             .withDefault(nullptr);
@@ -557,6 +568,7 @@
 
         // Explicitly release the camera
         pEnumerator->closeCamera(pCam);
+        activeCameras.clear();
     }
 }
 
@@ -568,7 +580,7 @@
  * which a human could observe to see the operation of the system on the physical display.
  */
 TEST_P(EvsHidlTest, CameraToDisplayRoundTrip) {
-    ALOGI("Starting CameraToDisplayRoundTrip test");
+    LOG(INFO) << "Starting CameraToDisplayRoundTrip test";
 
     // Get the camera list
     loadCameraList();
@@ -587,14 +599,14 @@
     // Request exclusive access to the first EVS display
     sp<IEvsDisplay_1_1> pDisplay = pEnumerator->openDisplay_1_1(targetDisplayId);
     ASSERT_NE(pDisplay, nullptr);
-    ALOGI("Display %d is in use.", targetDisplayId);
+    LOG(INFO) << "Display " << targetDisplayId << " is alreay in use.";
 
     // Get the display descriptor
     pDisplay->getDisplayInfo_1_1([](const auto& config, const auto& state) {
         android::DisplayConfig* pConfig = (android::DisplayConfig*)config.data();
         const auto width = pConfig->resolution.getWidth();
         const auto height = pConfig->resolution.getHeight();
-        ALOGI("    Resolution: %dx%d", width, height);
+        LOG(INFO) << "    Resolution: " << width << "x" << height;
         ASSERT_GT(width, 0);
         ASSERT_GT(height, 0);
 
@@ -607,11 +619,10 @@
         bool isLogicalCam = false;
         getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
         if (mIsHwModule && isLogicalCam) {
-            ALOGI("Skip a logical device %s for HW module", cam.v1.cameraId.c_str());
+            LOG(INFO) << "Skip a logical device " << cam.v1.cameraId << " for HW target.";
             continue;
         }
 
-        activeCameras.clear();
         sp<IEvsCamera_1_1> pCam =
             IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
             .withDefault(nullptr);
@@ -654,6 +665,7 @@
 
         // Explicitly release the camera
         pEnumerator->closeCamera(pCam);
+        activeCameras.clear();
     }
 
     // Explicitly release the display
@@ -667,7 +679,7 @@
  * underlying camera.
  */
 TEST_P(EvsHidlTest, MultiCameraStream) {
-    ALOGI("Starting MultiCameraStream test");
+    LOG(INFO) << "Starting MultiCameraStream test";
 
     if (mIsHwModule) {
         // This test is not for HW module implementation.
@@ -683,7 +695,6 @@
 
     // Test each reported camera
     for (auto&& cam: cameraInfo) {
-        activeCameras.clear();
         // Create two camera clients.
         sp<IEvsCamera_1_1> pCam0 =
             IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -735,7 +746,9 @@
         nsecs_t runTime = end - firstFrame;
         float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds);
         float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds);
-        ALOGI("Measured camera rate %3.2f fps and %3.2f fps", framesPerSecond0, framesPerSecond1);
+        LOG(INFO) << "Measured camera rate "
+                  << std::scientific << framesPerSecond0 << " fps and "
+                  << framesPerSecond1 << " fps";
         EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond);
         EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond);
 
@@ -760,6 +773,7 @@
         // Explicitly release the camera
         pEnumerator->closeCamera(pCam0);
         pEnumerator->closeCamera(pCam1);
+        activeCameras.clear();
 
         // TODO(b/145459970, b/145457727): below sleep() is added to ensure the
         // destruction of active camera objects; this may be related with two
@@ -774,7 +788,7 @@
  * Verify that a client can adjust a camera parameter.
  */
 TEST_P(EvsHidlTest, CameraParameter) {
-    ALOGI("Starting CameraParameter test");
+    LOG(INFO) << "Starting CameraParameter test";
 
     // Get the camera list
     loadCameraList();
@@ -791,11 +805,10 @@
         if (isLogicalCam) {
             // TODO(b/145465724): Support camera parameter programming on
             // logical devices.
-            ALOGI("Skip a logical device %s", cam.v1.cameraId.c_str());
+            LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
             continue;
         }
 
-        activeCameras.clear();
         // Create a camera client
         sp<IEvsCamera_1_1> pCam =
             IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -908,6 +921,7 @@
 
         // Explicitly release the camera
         pEnumerator->closeCamera(pCam);
+        activeCameras.clear();
     }
 }
 
@@ -918,7 +932,7 @@
  * terminates or releases a role.
  */
 TEST_P(EvsHidlTest, CameraMasterRelease) {
-    ALOGI("Starting CameraMasterRelease test");
+    LOG(INFO) << "Starting CameraMasterRelease test";
 
     if (mIsHwModule) {
         // This test is not for HW module implementation.
@@ -939,11 +953,10 @@
         if (isLogicalCam) {
             // TODO(b/145465724): Support camera parameter programming on
             // logical devices.
-            ALOGI("Skip a logical device %s", cam.v1.cameraId.c_str());
+            LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
             continue;
         }
 
-        activeCameras.clear();
         // Create two camera clients.
         sp<IEvsCamera_1_1> pCamMaster =
             IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -1012,7 +1025,7 @@
                 EvsEventDesc aTargetEvent;
                 aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
                 if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification, true)) {
-                    ALOGW("A timer is expired before a target event is fired.");
+                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                 }
 
             }
@@ -1057,7 +1070,7 @@
                 EvsEventDesc aTargetEvent;
                 aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
                 if (!frameHandlerMaster->waitForEvent(aTargetEvent, aNotification, true)) {
-                    ALOGW("A timer is expired before a target event is fired.");
+                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                 }
 
             }
@@ -1089,6 +1102,7 @@
         // Explicitly release the camera
         pEnumerator->closeCamera(pCamMaster);
         pEnumerator->closeCamera(pCamNonMaster);
+        activeCameras.clear();
     }
 }
 
@@ -1099,7 +1113,7 @@
  * camera parameters.
  */
 TEST_P(EvsHidlTest, MultiCameraParameter) {
-    ALOGI("Starting MultiCameraParameter test");
+    LOG(INFO) << "Starting MultiCameraParameter test";
 
     if (mIsHwModule) {
         // This test is not for HW module implementation.
@@ -1120,11 +1134,10 @@
         if (isLogicalCam) {
             // TODO(b/145465724): Support camera parameter programming on
             // logical devices.
-            ALOGI("Skip a logical device %s", cam.v1.cameraId.c_str());
+            LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
             continue;
         }
 
-        activeCameras.clear();
         // Create two camera clients.
         sp<IEvsCamera_1_1> pCamMaster =
             IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -1256,7 +1269,7 @@
                     aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
                     aTargetEvent.payload[1] = val0;
                     if (!frameHandlerMaster->waitForEvent(aTargetEvent, aNotification0)) {
-                        ALOGW("A timer is expired before a target event is fired.");
+                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                     }
                 }
             );
@@ -1273,7 +1286,7 @@
                     aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
                     aTargetEvent.payload[1] = val0;
                     if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification1)) {
-                        ALOGW("A timer is expired before a target event is fired.");
+                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                     }
                 }
             );
@@ -1374,7 +1387,7 @@
                 EvsEventDesc aTargetEvent;
                 aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
                 if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification0, true)) {
-                    ALOGW("A timer is expired before a target event is fired.");
+                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                 }
             }
         );
@@ -1466,7 +1479,7 @@
                     aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
                     aTargetEvent.payload[1] = val0;
                     if (!frameHandlerMaster->waitForEvent(aTargetEvent, aNotification0)) {
-                        ALOGW("A timer is expired before a target event is fired.");
+                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                     }
                 }
             );
@@ -1482,7 +1495,7 @@
                     aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
                     aTargetEvent.payload[1] = val0;
                     if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification1)) {
-                        ALOGW("A timer is expired before a target event is fired.");
+                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                     }
                 }
             );
@@ -1562,6 +1575,7 @@
         // Explicitly release the camera
         pEnumerator->closeCamera(pCamMaster);
         pEnumerator->closeCamera(pCamNonMaster);
+        activeCameras.clear();
     }
 }
 
@@ -1572,7 +1586,7 @@
  * a master role from other EVS clients without the display.
  */
 TEST_P(EvsHidlTest, HighPriorityCameraClient) {
-    ALOGI("Starting HighPriorityCameraClient test");
+    LOG(INFO) << "Starting HighPriorityCameraClient test";
 
     if (mIsHwModule) {
         // This test is not for HW module implementation.
@@ -1592,8 +1606,6 @@
 
     // Test each reported camera
     for (auto&& cam: cameraInfo) {
-        activeCameras.clear();
-
         // Create two clients
         sp<IEvsCamera_1_1> pCam0 =
             IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -1687,7 +1699,7 @@
                     aTargetEvent.payload[0] = static_cast<uint32_t>(CameraParam::AUTO_FOCUS);
                     aTargetEvent.payload[1] = 0;
                     if (!frameHandler0->waitForEvent(aTargetEvent, aNotification)) {
-                        ALOGW("A timer is expired before a target event is fired.");
+                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                     }
                 }
             );
@@ -1740,7 +1752,7 @@
                 aTargetEvent.payload[0] = static_cast<uint32_t>(cam1Cmds[0]);
                 aTargetEvent.payload[1] = val0;
                 if (!frameHandler1->waitForEvent(aTargetEvent, aNotification)) {
-                    ALOGW("A timer is expired before a target event is fired.");
+                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                 }
             }
         );
@@ -1791,7 +1803,7 @@
                 EvsEventDesc aTargetEvent;
                 aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
                 if (!frameHandler1->waitForEvent(aTargetEvent, aNotification, true)) {
-                    ALOGW("A timer is expired before a target event is fired.");
+                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                 }
             }
         );
@@ -1833,7 +1845,7 @@
                     aTargetEvent.payload[0] = static_cast<uint32_t>(CameraParam::AUTO_FOCUS);
                     aTargetEvent.payload[1] = 0;
                     if (!frameHandler1->waitForEvent(aTargetEvent, aNotification)) {
-                        ALOGW("A timer is expired before a target event is fired.");
+                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                     }
                 }
             );
@@ -1882,7 +1894,7 @@
                 aTargetEvent.payload[0] = static_cast<uint32_t>(cam0Cmds[0]);
                 aTargetEvent.payload[1] = val0;
                 if (!frameHandler0->waitForEvent(aTargetEvent, aNotification)) {
-                    ALOGW("A timer is expired before a target event is fired.");
+                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                 }
             }
         );
@@ -1931,6 +1943,8 @@
         // Explicitly release the camera
         pEnumerator->closeCamera(pCam0);
         pEnumerator->closeCamera(pCam1);
+        activeCameras.clear();
+
     }
 
     // Explicitly release the display
@@ -1945,7 +1959,7 @@
  * configurations from EVS and uses one of them to start a video stream.
  */
 TEST_P(EvsHidlTest, CameraUseStreamConfigToDisplay) {
-    ALOGI("Starting CameraUseStreamConfigToDisplay test");
+    LOG(INFO) << "Starting CameraUseStreamConfigToDisplay test";
 
     // Get the camera list
     loadCameraList();
@@ -1956,7 +1970,6 @@
 
     // Test each reported camera
     for (auto&& cam: cameraInfo) {
-        activeCameras.clear();
         // choose a configuration that has a frame rate faster than minReqFps.
         Stream targetCfg = {};
         const int32_t minReqFps = 15;
@@ -2036,6 +2049,7 @@
 
         // Explicitly release the camera
         pEnumerator->closeCamera(pCam);
+        activeCameras.clear();
     }
 
     // Explicitly release the display
@@ -2049,7 +2063,7 @@
  * underlying camera with same configuration.
  */
 TEST_P(EvsHidlTest, MultiCameraStreamUseConfig) {
-    ALOGI("Starting MultiCameraStream test");
+    LOG(INFO) << "Starting MultiCameraStream test";
 
     if (mIsHwModule) {
         // This test is not for HW module implementation.
@@ -2061,7 +2075,6 @@
 
     // Test each reported camera
     for (auto&& cam: cameraInfo) {
-        activeCameras.clear();
         // choose a configuration that has a frame rate faster than minReqFps.
         Stream targetCfg = {};
         const int32_t minReqFps = 15;
@@ -2094,9 +2107,8 @@
             static_cast<PixelFormat>(HAL_PIXEL_FORMAT_RGBA_8888);
 
         if (!foundCfg) {
-            ALOGI("Device %s does not provide a list of supported stream configurations, skipped",
-                  cam.v1.cameraId.c_str());
-
+            LOG(INFO) << "Device " << cam.v1.cameraId
+                      << " does not provide a list of supported stream configurations, skipped";
             continue;
         }
 
@@ -2162,7 +2174,9 @@
         nsecs_t runTime = end - firstFrame;
         float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds);
         float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds);
-        ALOGI("Measured camera rate %3.2f fps and %3.2f fps", framesPerSecond0, framesPerSecond1);
+        LOG(INFO) << "Measured camera rate "
+                  << std::scientific << framesPerSecond0 << " fps and "
+                  << framesPerSecond1 << " fps";
         EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond);
         EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond);
 
@@ -2187,6 +2201,7 @@
         // Explicitly release the camera
         pEnumerator->closeCamera(pCam0);
         pEnumerator->closeCamera(pCam1);
+        activeCameras.clear();
     }
 }
 
@@ -2198,7 +2213,7 @@
  * identifiers.
  */
 TEST_P(EvsHidlTest, LogicalCameraMetadata) {
-    ALOGI("Starting LogicalCameraMetadata test");
+    LOG(INFO) << "Starting LogicalCameraMetadata test";
 
     // Get the camera list
     loadCameraList();
@@ -2222,7 +2237,7 @@
  * can be reopened.
  */
 TEST_P(EvsHidlTest, UltrasonicsArrayOpenClean) {
-    ALOGI("Starting UltrasonicsArrayOpenClean test");
+    LOG(INFO) << "Starting UltrasonicsArrayOpenClean test";
 
     // Get the ultrasonics array list
     loadUltrasonicsArrayList();
@@ -2236,7 +2251,7 @@
 
             // Verify that this ultrasonics array self-identifies correctly
             pUltrasonicsArray->getUltrasonicArrayInfo([&ultraInfo](UltrasonicsArrayDesc desc) {
-                ALOGD("Found ultrasonics array %s", ultraInfo.ultrasonicsArrayId.c_str());
+                LOG(DEBUG) << "Found ultrasonics array " << ultraInfo.ultrasonicsArrayId;
                 EXPECT_EQ(ultraInfo.ultrasonicsArrayId, desc.ultrasonicsArrayId);
             });
 
@@ -2249,14 +2264,14 @@
 
 // Starts a stream and verifies all data received is valid.
 TEST_P(EvsHidlTest, UltrasonicsVerifyStreamData) {
-    ALOGI("Starting UltrasonicsVerifyStreamData");
+    LOG(INFO) << "Starting UltrasonicsVerifyStreamData";
 
     // Get the ultrasonics array list
     loadUltrasonicsArrayList();
 
     // For each ultrasonics array.
     for (auto&& ultraInfo : ultrasonicsArraysInfo) {
-        ALOGD("Testing ultrasonics array: %s", ultraInfo.ultrasonicsArrayId.c_str());
+        LOG(DEBUG) << "Testing ultrasonics array: " << ultraInfo.ultrasonicsArrayId;
 
         sp<IEvsUltrasonicsArray> pUltrasonicsArray =
                 pEnumerator->openUltrasonicsArray(ultraInfo.ultrasonicsArrayId);
@@ -2285,14 +2300,14 @@
 
 // Sets frames in flight before and after start of stream and verfies success.
 TEST_P(EvsHidlTest, UltrasonicsSetFramesInFlight) {
-    ALOGI("Starting UltrasonicsSetFramesInFlight");
+    LOG(INFO) << "Starting UltrasonicsSetFramesInFlight";
 
     // Get the ultrasonics array list
     loadUltrasonicsArrayList();
 
     // For each ultrasonics array.
     for (auto&& ultraInfo : ultrasonicsArraysInfo) {
-        ALOGD("Testing ultrasonics array: %s", ultraInfo.ultrasonicsArrayId.c_str());
+        LOG(DEBUG) << "Testing ultrasonics array: " << ultraInfo.ultrasonicsArrayId;
 
         sp<IEvsUltrasonicsArray> pUltrasonicsArray =
                 pEnumerator->openUltrasonicsArray(ultraInfo.ultrasonicsArrayId);
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h
index e3cbf2e..f2d3c13 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h
@@ -206,7 +206,7 @@
         InternalPool(VehiclePropertyType type, size_t vectorSize)
             : mPropType(type), mVectorSize(vectorSize) {}
 
-        RecyclableType obtain() {
+        RecyclableType obtain() override {
             return ObjectPool<VehiclePropValue>::obtain();
         }
     protected:
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index 6d5f23f..b76aff9 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -15,8 +15,9 @@
  */
 #define LOG_TAG "DefaultVehicleHal_v2_0"
 
-#include <android/log.h>
 #include <android-base/macros.h>
+#include <android/log.h>
+#include <sys/system_properties.h>
 
 #include "EmulatedVehicleHal.h"
 #include "JsonFakeValueGenerator.h"
@@ -186,6 +187,14 @@
         return StatusCode::NOT_AVAILABLE;
     }
 
+    if (mInEmulator && propValue.prop == toInt(VehicleProperty::DISPLAY_BRIGHTNESS)) {
+        // Emulator does not support remote brightness control, b/139959479
+        // do not send it down so that it does not bring unnecessary property change event
+        // return other error code, such NOT_AVAILABLE, causes Emulator to be freezing
+        // TODO: return StatusCode::NOT_AVAILABLE once the above issue is fixed
+        return StatusCode::OK;
+    }
+
     /**
      * After checking all conditions, such as the property is available, a real vhal will
      * sent the events to Car ECU to take actions.
@@ -211,6 +220,17 @@
     return false;
 }
 
+// determine if it's running inside Android Emulator
+static bool isInEmulator() {
+    char propValue[PROP_VALUE_MAX];
+    bool isEmulator = (__system_property_get("ro.kernel.qemu", propValue) != 0);
+    if (!isEmulator) {
+        isEmulator = (__system_property_get("ro.hardware", propValue) != 0) &&
+                     (!strcmp(propValue, "ranchu") || !strcmp(propValue, "goldfish"));
+    }
+    return isEmulator;
+}
+
 // Parse supported properties list and generate vector of property values to hold current values.
 void EmulatedVehicleHal::onCreate() {
     static constexpr bool shouldUpdateStatus = true;
@@ -261,6 +281,8 @@
     }
     initObd2LiveFrame(*mPropStore->getConfigOrDie(OBD2_LIVE_FRAME));
     initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME));
+    mInEmulator = isInEmulator();
+    ALOGD("mInEmulator=%s", mInEmulator ? "true" : "false");
 }
 
 std::vector<VehiclePropConfig> EmulatedVehicleHal::listProperties()  {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index ebf1995..dc05145 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -86,6 +86,7 @@
     std::unordered_set<int32_t> mHvacPowerProps;
     RecurrentTimer mRecurrentTimer;
     VehicleHalClient* mVehicleClient;
+    bool mInEmulator;
 };
 
 }  // impl
diff --git a/bluetooth/1.1/IBluetoothHci.hal b/bluetooth/1.1/IBluetoothHci.hal
index 0f69c6e..2a520c1 100644
--- a/bluetooth/1.1/IBluetoothHci.hal
+++ b/bluetooth/1.1/IBluetoothHci.hal
@@ -35,8 +35,8 @@
     initialize_1_1(@1.1::IBluetoothHciCallbacks callback);
 
     /**
-     * Send an ISO data packet (as specified in the Bluetooth Specification
-     * V6.0) to the Bluetooth controller.
+     * Send an ISO data packet (as specified in the Bluetooth Core
+     * Specification v5.2) to the Bluetooth controller.
      * Packets must be processed in order.
      * @param data HCI data packet to be sent
      */
diff --git a/cas/1.2/vts/functional/Android.bp b/cas/1.2/vts/functional/Android.bp
index 9bc372c..2d6517f 100644
--- a/cas/1.2/vts/functional/Android.bp
+++ b/cas/1.2/vts/functional/Android.bp
@@ -31,6 +31,8 @@
     shared_libs: [
         "libbinder",
     ],
-    test_suites: ["general-tests"],
+    test_suites: [
+        "general-tests",
+        "vts-core",
+    ],
 }
-
diff --git a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp
index 8439ceb..58e0f2e 100644
--- a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp
+++ b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp
@@ -16,8 +16,6 @@
 
 #define LOG_TAG "mediacas_hidl_hal_test"
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/cas/1.0/IDescramblerBase.h>
 #include <android/hardware/cas/1.0/types.h>
@@ -28,8 +26,11 @@
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
 #include <android/hardware/cas/native/1.0/types.h>
 #include <binder/MemoryDealer.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
 #include <hidl/HidlSupport.h>
 #include <hidl/HidlTransportSupport.h>
+#include <hidl/ServiceManagement.h>
 #include <hidl/Status.h>
 #include <hidlmemory/FrameworkUtils.h>
 #include <utils/Condition.h>
@@ -293,27 +294,14 @@
     EXPECT_EQ(mEventArg, static_cast<int32_t>(mode));
 }
 
-// Test environment for Cas HIDL HAL.
-class CasHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-  public:
-    // get the test environment singleton
-    static CasHidlEnvironment* Instance() {
-        static CasHidlEnvironment* instance = new CasHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IMediaCasService>(); }
-};
-
-class MediaCasHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class MediaCasHidlTest : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
-        mService = ::testing::VtsHalHidlTargetTestBase::getService<IMediaCasService>(
-                CasHidlEnvironment::Instance()->getServiceName<IMediaCasService>());
+        mService = IMediaCasService::getService(GetParam());
         ASSERT_NE(mService, nullptr);
     }
 
-    sp<IMediaCasService> mService;
+    sp<IMediaCasService> mService = nullptr;
 
   protected:
     static void description(const std::string& description) {
@@ -497,7 +485,7 @@
     return ::testing::AssertionResult(returnVoid.isOk());
 }
 
-TEST_F(MediaCasHidlTest, TestClearKeyApisWithSession) {
+TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) {
     description("Test that valid call sequences with SessionEvent send and receive");
 
     ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
@@ -609,11 +597,7 @@
 
 }  // anonymous namespace
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(CasHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    CasHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, MediaCasHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMediaCasService::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/current.txt b/current.txt
index a6f35ba..d8f9c08 100644
--- a/current.txt
+++ b/current.txt
@@ -589,6 +589,7 @@
 a05277065c28ebecd58118bd240fb8c55757361e8648c01f7c4dacdb7f2a95dc android.hardware.camera.metadata@3.3::types
 9cb3df2bde2c6cd5fd96b7c41555420cacd7e276a556c684af91b7461c86460f android.hardware.gnss@1.0::IGnssCallback
 af334f1fc85c62b343f84b74d0495eed6f495f7fecedb53463db10c202310058 android.hardware.gnss.measurement_corrections@1.0::types
+33a6b20c43af00fdfb305df891bc5911c06d9a9130b912759649932e5a4a6e6d android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControlCallback
 bceee81ec1b59324abd05932b5620fda5a6589597c9cb3953ba7f3ea02cccd3e android.hardware.camera.provider@2.4::ICameraProvider
 2ce820dc4f3c6d85721b65150ed2157c6e2e2055f866fb6c6ba4790f14408d66 android.hardware.camera.provider@2.4::ICameraProviderCallback
 b69a7615c508acf5c5201efd1bfa3262167874fc3594e2db5a3ff93addd8ac75 android.hardware.keymaster@4.0::IKeymasterDevice
@@ -634,7 +635,7 @@
 ae6315fd42196478ac08441cb489d854118001bca5b9b9fd58af5110952be30e android.hardware.biometrics.fingerprint@2.2::types
 6828bbf18dc5d0f00c73341a10c8e4d574346c1abb1c2ed682ba5e9f8a3240d9 android.hardware.biometrics.fingerprint@2.2::IBiometricsFingerprint
 82cad99f5feb2ea9bcd4579055edf4af8feb9fc602a6e4827ddd727d254d4991 android.hardware.biometrics.fingerprint@2.2::IBiometricsFingerprintClientCallback
-79e115c8f8970b8b914bafc66df5425e065fda4dcda97222966ef12451d2a1cc android.hardware.bluetooth@1.1::IBluetoothHci
+362fd1c21641c2224f3b80c30d9797b988fa3f344243d531ba73c553779a5763 android.hardware.bluetooth@1.1::IBluetoothHci
 40ab2c6866c18d32baf6e49e3053949e79601f56963a791e93e68b9ee18f718d android.hardware.bluetooth@1.1::IBluetoothHciCallbacks
 07d0a252b2d8fa35887908a996ba395cf392968395fc30afab791f46e0c22a52 android.hardware.boot@1.1::IBootControl
 74049a402be913963edfdd80828a53736570e9d8124a1bf18166b6ed46a6b0ab android.hardware.boot@1.1::types
@@ -680,7 +681,7 @@
 6e904be0ddca5ae1de8eba020e6c38ed935ea7d80cd08f47787f137a0ca58555 android.hardware.neuralnetworks@1.3::IFencedExecutionCallback
 2b0b10d2ea7a18a4048cd0eb83d35c19a817aeee95f65807fc31f4ef21381397 android.hardware.neuralnetworks@1.3::IPreparedModel
 eee3430cc86c97c7b407495863d8fb61da6f1a64b7721e77b9b4909b11b174e9 android.hardware.neuralnetworks@1.3::IPreparedModelCallback
-c9320b04ec302624985180a02d591bea5e435601fc411a6cabb58878e4e1ad68 android.hardware.neuralnetworks@1.3::types
+e442ab1b440327fe4e8a3b0b8ac6874e9bc6342e91fe976eb9fea77c63961ec8 android.hardware.neuralnetworks@1.3::types
 b335c3c732c799b299fa61c6de6260ab4d20cbd0ec21acd6db14d8156c745d0b android.hardware.tv.tuner@1.0::types
 adab52e647d1a1ccfbdabdfc9c73352f8e834b61322e505bc6e3d3a0d3acc259 android.hardware.tv.tuner@1.0::IDemux
 548e1a16fc4f779346e14968a63cd6f160e1e2c8b8c99256b2bac24a24b52a9a android.hardware.tv.tuner@1.0::IDescrambler
diff --git a/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal b/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal
index 5a582c2..5ee2923 100644
--- a/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal
+++ b/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal
@@ -82,6 +82,9 @@
         /**
          * Package name of the Android proxy application representing the non-framework
          * entity that requested location. Set to empty string if unknown.
+         *
+         * For user-initiated emergency use cases, this field must be set to empty string
+         * and the inEmergencyMode field must be set to true.
          */
         string proxyAppPackageName;
 
@@ -157,4 +160,4 @@
      * @return success True if the framework determines that the device is in emergency session.
      */
     isInEmergencySession() generates (bool success);
-};
\ No newline at end of file
+};
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl
index 3fca53b..c04cef0 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl
@@ -39,7 +39,7 @@
     /**
      * The type of this plane layout component.
      *
-     * android.hardware.graphics.common.PlaneLayoutComponent defines the standard
+     * android.hardware.graphics.common.PlaneLayoutComponentType defines the standard
      * plane layout component types. Vendors may extend this type to include any
      * non-standard plane layout component types. For instructions on how to
      * create a vendor extension, refer to ExtendableType.aidl.
diff --git a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
index 1185945..3d792f9 100644
--- a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
+++ b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
@@ -94,7 +94,7 @@
                                                     mDummyDescriptorInfo.width);
     ASSERT_EQ(Error::BAD_BUFFER, ret)
         << "validateBufferSize with raw buffer handle did not fail with BAD_BUFFER";
-    native_handle_delete(rawBufferHandle);
+    ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(rawBufferHandle));
 }
 
 /**
@@ -179,11 +179,11 @@
     ASSERT_NO_FATAL_FAILURE(rawBufferHandle = const_cast<native_handle_t*>(
                                 mGralloc->allocate(mDummyDescriptorInfo, false)));
     mGralloc->getMapper()->getTransportSize(
-        invalidHandle, [&](const auto& tmpError, const auto&, const auto&) {
-            ASSERT_EQ(Error::BAD_BUFFER, tmpError)
-                << "getTransportSize with raw buffer handle did not fail with BAD_BUFFER";
-        });
-    native_handle_delete(rawBufferHandle);
+            rawBufferHandle, [&](const auto& tmpError, const auto&, const auto&) {
+                ASSERT_EQ(Error::BAD_BUFFER, tmpError)
+                        << "getTransportSize with raw buffer handle did not fail with BAD_BUFFER";
+            });
+    ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(rawBufferHandle));
 }
 
 /**
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 6cc5e34..a783eaa 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -2124,8 +2124,14 @@
 
         Error err;
         mGralloc->getAllocator()->allocate(
-                descriptor, 1,
-                [&](const auto& tmpError, const auto&, const auto&) { err = tmpError; });
+                descriptor, 1, [&](const auto& tmpError, const auto&, const auto& tmpBuffers) {
+                    err = tmpError;
+                    if (err == Error::NONE) {
+                        ASSERT_EQ(1, tmpBuffers.size());
+                        ASSERT_NO_FATAL_FAILURE(bufferHandle =
+                                                        mGralloc->importBuffer(tmpBuffers[0]));
+                    }
+                });
         if (err == Error::UNSUPPORTED) {
             continue;
         }
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 10ce4c2..cc14271 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -176,6 +176,10 @@
      * @param itemsRequest
      *   If non-empty, contains request data that is signed by the reader. See above.
      *
+     * @param signingKeyBlob is either empty or a signingKeyBlob (see generateSigningKeyPair(),
+     *    below) containing the signing key to use to sign the data retrieved. If this
+     *    is not in the right format the call fails with STATUS_INVALID_DATA.
+     *
      * @param sessionTranscript
      *   Either empty or the CBOR of the SessionTranscript. See above.
      *
@@ -195,8 +199,7 @@
      *   and remove the corresponding requests from the counts.
      */
     void startRetrieval(in SecureAccessControlProfile[] accessControlProfiles,
-        in HardwareAuthToken authToken,
-        in byte[] itemsRequest,
+        in HardwareAuthToken authToken, in byte[] itemsRequest, in byte[] signingKeyBlob,
         in byte[] sessionTranscript, in byte[] readerSignature, in int[] requestCounts);
 
     /**
@@ -254,10 +257,6 @@
      * If signingKeyBlob or the sessionTranscript parameter passed to startRetrieval() is
      * empty then the returned MAC will be empty.
      *
-     * @param signingKeyBlob is either empty or a signingKeyBlob (see generateSigningKeyPair(),
-     *    below) containing the signing key to use to sign the data retrieved. If this
-     *    is not in the right format the call fails with STATUS_INVALID_DATA.
-     *
      * @param out mac is empty if signingKeyBlob or the sessionTranscript passed to
      *    startRetrieval() is empty. Otherwise it is a COSE_Mac0 with empty payload
      *    and the detached content is set to DeviceAuthentication as defined below.
@@ -304,7 +303,7 @@
      *
      * @param out deviceNameSpaces the bytes of DeviceNameSpaces.
      */
-    void finishRetrieval(in byte[] signingKeyBlob, out byte[] mac, out byte[] deviceNameSpaces);
+    void finishRetrieval(out byte[] mac, out byte[] deviceNameSpaces);
 
     /**
      * Generate a key pair to be used for signing session data and retrieved data items.
diff --git a/identity/aidl/default/IdentityCredential.cpp b/identity/aidl/default/IdentityCredential.cpp
index d5b3a0f..341fae6 100644
--- a/identity/aidl/default/IdentityCredential.cpp
+++ b/identity/aidl/default/IdentityCredential.cpp
@@ -256,8 +256,8 @@
 ndk::ScopedAStatus IdentityCredential::startRetrieval(
         const vector<SecureAccessControlProfile>& accessControlProfiles,
         const HardwareAuthToken& authToken, const vector<int8_t>& itemsRequestS,
-        const vector<int8_t>& sessionTranscriptS, const vector<int8_t>& readerSignatureS,
-        const vector<int32_t>& requestCounts) {
+        const vector<int8_t>& signingKeyBlobS, const vector<int8_t>& sessionTranscriptS,
+        const vector<int8_t>& readerSignatureS, const vector<int32_t>& requestCounts) {
     auto sessionTranscript = byteStringToUnsigned(sessionTranscriptS);
     auto itemsRequest = byteStringToUnsigned(itemsRequestS);
     auto readerSignature = byteStringToUnsigned(readerSignatureS);
@@ -498,6 +498,7 @@
     currentNameSpace_ = "";
 
     itemsRequest_ = itemsRequest;
+    signingKeyBlob_ = byteStringToUnsigned(signingKeyBlobS);
 
     numStartRetrievalCalls_ += 1;
     return ndk::ScopedAStatus::ok();
@@ -650,11 +651,8 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus IdentityCredential::finishRetrieval(const vector<int8_t>& signingKeyBlobS,
-                                                       vector<int8_t>* outMac,
+ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<int8_t>* outMac,
                                                        vector<int8_t>* outDeviceNameSpaces) {
-    auto signingKeyBlob = byteStringToUnsigned(signingKeyBlobS);
-
     if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) {
         deviceNameSpacesMap_.add(currentNameSpace_,
                                  std::move(currentNameSpaceDeviceNameSpacesMap_));
@@ -664,7 +662,8 @@
     // If there's no signing key or no sessionTranscript or no reader ephemeral
     // public key, we return the empty MAC.
     optional<vector<uint8_t>> mac;
-    if (signingKeyBlob.size() > 0 && sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0) {
+    if (signingKeyBlob_.size() > 0 && sessionTranscript_.size() > 0 &&
+        readerPublicKey_.size() > 0) {
         cppbor::Array array;
         array.add("DeviceAuthentication");
         array.add(sessionTranscriptItem_->clone());
@@ -674,7 +673,7 @@
 
         vector<uint8_t> docTypeAsBlob(docType_.begin(), docType_.end());
         optional<vector<uint8_t>> signingKey =
-                support::decryptAes128Gcm(storageKey_, signingKeyBlob, docTypeAsBlob);
+                support::decryptAes128Gcm(storageKey_, signingKeyBlob_, docTypeAsBlob);
         if (!signingKey) {
             return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                     IIdentityCredentialStore::STATUS_INVALID_DATA,
diff --git a/identity/aidl/default/IdentityCredential.h b/identity/aidl/default/IdentityCredential.h
index 49ed0d4..fc29254 100644
--- a/identity/aidl/default/IdentityCredential.h
+++ b/identity/aidl/default/IdentityCredential.h
@@ -54,14 +54,14 @@
     ndk::ScopedAStatus startRetrieval(
             const vector<SecureAccessControlProfile>& accessControlProfiles,
             const HardwareAuthToken& authToken, const vector<int8_t>& itemsRequest,
-            const vector<int8_t>& sessionTranscript, const vector<int8_t>& readerSignature,
-            const vector<int32_t>& requestCounts) override;
+            const vector<int8_t>& signingKeyBlob, const vector<int8_t>& sessionTranscript,
+            const vector<int8_t>& readerSignature, const vector<int32_t>& requestCounts) override;
     ndk::ScopedAStatus startRetrieveEntryValue(
             const string& nameSpace, const string& name, int32_t entrySize,
             const vector<int32_t>& accessControlProfileIds) override;
     ndk::ScopedAStatus retrieveEntryValue(const vector<int8_t>& encryptedContent,
                                           vector<int8_t>* outContent) override;
-    ndk::ScopedAStatus finishRetrieval(const vector<int8_t>& signingKeyBlob, vector<int8_t>* outMac,
+    ndk::ScopedAStatus finishRetrieval(vector<int8_t>* outMac,
                                        vector<int8_t>* outDeviceNameSpaces) override;
     ndk::ScopedAStatus generateSigningKeyPair(vector<int8_t>* outSigningKeyBlob,
                                               Certificate* outSigningKeyCertificate) override;
@@ -88,6 +88,7 @@
 
     // Set at startRetrieval() time.
     map<int32_t, int> profileIdToAccessCheckResult_;
+    vector<uint8_t> signingKeyBlob_;
     vector<uint8_t> sessionTranscript_;
     std::unique_ptr<cppbor::Item> sessionTranscriptItem_;
     vector<uint8_t> itemsRequest_;
diff --git a/identity/aidl/default/WritableIdentityCredential.cpp b/identity/aidl/default/WritableIdentityCredential.cpp
index ba2062d..89f7f35 100644
--- a/identity/aidl/default/WritableIdentityCredential.cpp
+++ b/identity/aidl/default/WritableIdentityCredential.cpp
@@ -16,6 +16,9 @@
 
 #define LOG_TAG "WritableIdentityCredential"
 
+#include "WritableIdentityCredential.h"
+#include "IdentityCredentialStore.h"
+
 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
 
 #include <android-base/logging.h>
@@ -23,6 +26,8 @@
 #include <cppbor/cppbor.h>
 #include <cppbor/cppbor_parse.h>
 
+#include <utility>
+
 #include "IdentityCredentialStore.h"
 #include "Util.h"
 #include "WritableIdentityCredential.h"
@@ -33,26 +38,6 @@
 using namespace ::android::hardware::identity;
 
 bool WritableIdentityCredential::initialize() {
-    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
-    if (!keyPair) {
-        LOG(ERROR) << "Error creating credentialKey";
-        return false;
-    }
-
-    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
-    if (!pubKey) {
-        LOG(ERROR) << "Error getting public part of credentialKey";
-        return false;
-    }
-    credentialPubKey_ = pubKey.value();
-
-    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
-    if (!privKey) {
-        LOG(ERROR) << "Error getting private part of credentialKey";
-        return false;
-    }
-    credentialPrivKey_ = privKey.value();
-
     optional<vector<uint8_t>> random = support::getRandom(16);
     if (!random) {
         LOG(ERROR) << "Error creating storageKey";
@@ -63,88 +48,54 @@
     return true;
 }
 
-// TODO: use |attestationApplicationId| and |attestationChallenge| and also
-//       ensure the returned certificate chain satisfy the requirements listed in
-//       the docs for IWritableIdentityCredential::getAttestationCertificate()
-//
+// This function generates the attestation certificate using the passed in
+// |attestationApplicationId| and |attestationChallenge|.  It will generate an
+// attestation certificate with current time and expires one year from now.  The
+// certificate shall contain all values as specified in hal.
 ndk::ScopedAStatus WritableIdentityCredential::getAttestationCertificate(
-        const vector<int8_t>& /*attestationApplicationId*/,
-        const vector<int8_t>& /*attestationChallenge*/, vector<Certificate>* outCertificateChain) {
-    // For now, we dynamically generate an attestion key on each and every
-    // request and use that to sign CredentialKey. In a real implementation this
-    // would look very differently.
-    optional<vector<uint8_t>> attestationKeyPair = support::createEcKeyPair();
-    if (!attestationKeyPair) {
-        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                IIdentityCredentialStore::STATUS_FAILED, "Error creating attestationKey"));
-    }
-
-    optional<vector<uint8_t>> attestationPubKey =
-            support::ecKeyPairGetPublicKey(attestationKeyPair.value());
-    if (!attestationPubKey) {
+        const vector<int8_t>& attestationApplicationId,  //
+        const vector<int8_t>& attestationChallenge,      //
+        vector<Certificate>* outCertificateChain) {
+    if (!credentialPrivKey_.empty() || !credentialPubKey_.empty() || !certificateChain_.empty()) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_FAILED,
-                "Error getting public part of attestationKey"));
+                "Error attestation certificate previously generated"));
     }
 
-    optional<vector<uint8_t>> attestationPrivKey =
-            support::ecKeyPairGetPrivateKey(attestationKeyPair.value());
-    if (!attestationPrivKey) {
+    vector<uint8_t> challenge(attestationChallenge.begin(), attestationChallenge.end());
+    vector<uint8_t> appId(attestationApplicationId.begin(), attestationApplicationId.end());
+
+    optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> keyAttestationPair =
+            support::createEcKeyPairAndAttestation(challenge, appId);
+    if (!keyAttestationPair) {
+        LOG(ERROR) << "Error creating credentialKey and attestation";
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_FAILED,
-                "Error getting private part of attestationKey"));
+                "Error creating credentialKey and attestation"));
     }
 
-    string serialDecimal;
-    string issuer;
-    string subject;
-    time_t validityNotBefore = time(nullptr);
-    time_t validityNotAfter = validityNotBefore + 365 * 24 * 3600;
+    vector<uint8_t> keyPair = keyAttestationPair.value().first;
+    certificateChain_ = keyAttestationPair.value().second;
 
-    // First create a certificate for |credentialPubKey| which is signed by
-    // |attestationPrivKey|.
-    //
-    serialDecimal = "0";  // TODO: set serial to |attestationChallenge|
-    issuer = "Android Open Source Project";
-    subject = "Android IdentityCredential CredentialKey";
-    optional<vector<uint8_t>> credentialPubKeyCertificate = support::ecPublicKeyGenerateCertificate(
-            credentialPubKey_, attestationPrivKey.value(), serialDecimal, issuer, subject,
-            validityNotBefore, validityNotAfter);
-    if (!credentialPubKeyCertificate) {
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair);
+    if (!pubKey) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_FAILED,
-                "Error creating certificate for credentialPubKey"));
+                "Error getting public part of credentialKey"));
     }
+    credentialPubKey_ = pubKey.value();
 
-    // This is followed by a certificate for |attestationPubKey| self-signed by
-    // |attestationPrivKey|.
-    serialDecimal = "0";  // TODO: set serial
-    issuer = "Android Open Source Project";
-    subject = "Android IdentityCredential AttestationKey";
-    optional<vector<uint8_t>> attestationKeyCertificate = support::ecPublicKeyGenerateCertificate(
-            attestationPubKey.value(), attestationPrivKey.value(), serialDecimal, issuer, subject,
-            validityNotBefore, validityNotAfter);
-    if (!attestationKeyCertificate) {
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair);
+    if (!privKey) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_FAILED,
-                "Error creating certificate for attestationPubKey"));
+                "Error getting private part of credentialKey"));
     }
+    credentialPrivKey_ = privKey.value();
 
-    // Concatenate the certificates to form the chain.
-    vector<uint8_t> certificateChain;
-    certificateChain.insert(certificateChain.end(), credentialPubKeyCertificate.value().begin(),
-                            credentialPubKeyCertificate.value().end());
-    certificateChain.insert(certificateChain.end(), attestationKeyCertificate.value().begin(),
-                            attestationKeyCertificate.value().end());
-
-    optional<vector<vector<uint8_t>>> splitCertChain =
-            support::certificateChainSplit(certificateChain);
-    if (!splitCertChain) {
-        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                IIdentityCredentialStore::STATUS_FAILED, "Error splitting certificate chain"));
-    }
+    // convert from vector<vector<uint8_t>>> to vector<Certificate>*
     *outCertificateChain = vector<Certificate>();
-    for (const vector<uint8_t>& cert : splitCertChain.value()) {
+    for (const vector<uint8_t>& cert : certificateChain_) {
         Certificate c = Certificate();
         c.encodedCertificate = byteStringToSigned(cert);
         outCertificateChain->push_back(std::move(c));
diff --git a/identity/aidl/default/WritableIdentityCredential.h b/identity/aidl/default/WritableIdentityCredential.h
index b380f89..b182862 100644
--- a/identity/aidl/default/WritableIdentityCredential.h
+++ b/identity/aidl/default/WritableIdentityCredential.h
@@ -64,10 +64,13 @@
     string docType_;
     bool testCredential_;
 
-    // These are set in initialize().
+    // This is set in initialize().
     vector<uint8_t> storageKey_;
+
+    // These are set in getAttestationCertificate().
     vector<uint8_t> credentialPrivKey_;
     vector<uint8_t> credentialPubKey_;
+    vector<vector<uint8_t>> certificateChain_;
 
     // These fields are initialized during startPersonalization()
     size_t numAccessControlProfileRemaining_;
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 21ff440..cecc814 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -7,10 +7,11 @@
     srcs: ["VtsHalIdentityTargetTest.cpp"],
     shared_libs: [
         "libbinder",
-        "libcppbor",
-        "android.hardware.identity-support-lib",
+        "libcrypto",
     ],
     static_libs: [
+        "libcppbor",
+        "android.hardware.identity-support-lib",
         "android.hardware.identity-cpp",
         "android.hardware.keymaster-cpp",
     ],
diff --git a/identity/aidl/vts/VtsHalIdentityTargetTest.cpp b/identity/aidl/vts/VtsHalIdentityTargetTest.cpp
index 5abe5a2..ea37fdc 100644
--- a/identity/aidl/vts/VtsHalIdentityTargetTest.cpp
+++ b/identity/aidl/vts/VtsHalIdentityTargetTest.cpp
@@ -352,10 +352,15 @@
                                    readerCertificate.value());
     ASSERT_TRUE(readerSignature);
 
+    // Generate the key that will be used to sign AuthenticatedData.
+    vector<uint8_t> signingKeyBlob;
+    Certificate signingKeyCertificate;
+    ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
+
     ASSERT_TRUE(credential
                         ->startRetrieval(returnedSecureProfiles, authToken, itemsRequestBytes,
-                                         sessionTranscriptBytes, readerSignature.value(),
-                                         testEntriesEntryCounts)
+                                         signingKeyBlob, sessionTranscriptBytes,
+                                         readerSignature.value(), testEntriesEntryCounts)
                         .isOk());
 
     for (const auto& entry : testEntries) {
@@ -377,14 +382,9 @@
         EXPECT_EQ(content, entry.valueCbor);
     }
 
-    // Generate the key that will be used to sign AuthenticatedData.
-    vector<uint8_t> signingKeyBlob;
-    Certificate signingKeyCertificate;
-    ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
-
     vector<uint8_t> mac;
     vector<uint8_t> deviceNameSpacesBytes;
-    ASSERT_TRUE(credential->finishRetrieval(signingKeyBlob, &mac, &deviceNameSpacesBytes).isOk());
+    ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesBytes).isOk());
     cborPretty = support::cborPrettyPrint(deviceNameSpacesBytes, 32, {});
     ASSERT_EQ(
             "{\n"
diff --git a/identity/support/Android.bp b/identity/support/Android.bp
index 7b4546b..2b6c695 100644
--- a/identity/support/Android.bp
+++ b/identity/support/Android.bp
@@ -23,10 +23,14 @@
         "include",
     ],
     shared_libs: [
+        "android.hardware.keymaster@4.0",
         "libcrypto",
         "libbase",
         "libhidlbase",
         "libhardware",
+        "libkeymaster_portable",
+        "libsoft_attestation_cert",
+        "libpuresoftkeymasterdevice",
     ],
     static_libs: [
         "libcppbor",
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
index 4533ad9..507e914 100644
--- a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -21,6 +21,7 @@
 #include <optional>
 #include <string>
 #include <tuple>
+#include <utility>
 #include <vector>
 
 namespace android {
@@ -106,6 +107,17 @@
 // ---------------------------------------------------------------------------
 // EC crypto functionality / abstraction (only supports P-256).
 // ---------------------------------------------------------------------------
+// Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the
+// PKCS#8 encoded key-pair.  Also generates an attestation
+// certificate using the |challenge| and |applicationId|, and returns the generated
+// certificate in X.509 certificate chain format.
+//
+// The attestation time fields used will be the current time, and expires in one year.
+//
+// The first parameter of the return value is the keyPair generated, second return in
+// the pair is the attestation certificate generated.
+optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
+        const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId);
 
 // Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the
 // PKCS#8 encoded key-pair.
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index e2828bf..bf6a5c3 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -47,6 +47,13 @@
 #include <cppbor.h>
 #include <cppbor_parse.h>
 
+#include <android/hardware/keymaster/4.0/types.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/contexts/pure_soft_keymaster_context.h>
+#include <keymaster/contexts/soft_attestation_cert.h>
+#include <keymaster/keymaster_tags.h>
+#include <keymaster/km_openssl/attestation_utils.h>
+
 namespace android {
 namespace hardware {
 namespace identity {
@@ -816,6 +823,138 @@
     return hmac;
 }
 
+// Generates the attestation certificate with the parameters passed in.  Note
+// that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
+// milli seconds since epoch.  We are setting them to milliseconds due to
+// requirement in AuthorizationSet KM_DATE fields.  The certificate created is
+// actually in seconds.
+optional<vector<vector<uint8_t>>> createAttestation(const EVP_PKEY* key,
+                                                    const vector<uint8_t>& applicationId,
+                                                    const vector<uint8_t>& challenge,
+                                                    uint64_t activeTimeMilliSeconds,
+                                                    uint64_t expireTimeMilliSeconds) {
+    ::keymaster::AuthorizationSet auth_set(
+            ::keymaster::AuthorizationSetBuilder()
+                    .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
+                                   challenge.size())
+                    .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
+                    // Even though identity attestation hal said the application
+                    // id should be in software enforced authentication set,
+                    // keymaster portable lib expect the input in this
+                    // parameter because the software enforced in input to keymaster
+                    // refers to the key software enforced properties. And this
+                    // parameter refers to properties of the attestation which
+                    // includes app id.
+                    .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
+                                   applicationId.data(), applicationId.size())
+                    .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
+
+    // Unique id and device id is not applicable for identity credential attestation,
+    // so we don't need to set those or application id.
+    ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
+            ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
+
+    ::keymaster::AuthorizationSet hwEnforced(
+            ::keymaster::AuthorizationSetBuilder()
+                    .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
+                    .Authorization(::keymaster::TAG_KEY_SIZE, 256)
+                    .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
+                    .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
+                    .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
+                    .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
+                    .Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY));
+
+    const keymaster_cert_chain_t* attestation_chain =
+            ::keymaster::getAttestationChain(KM_ALGORITHM_EC, nullptr);
+
+    if (attestation_chain == nullptr) {
+        LOG(ERROR) << "Error getting attestation chain";
+        return {};
+    }
+
+    const keymaster_key_blob_t* attestation_signing_key =
+            ::keymaster::getAttestationKey(KM_ALGORITHM_EC, nullptr);
+    if (attestation_signing_key == nullptr) {
+        LOG(ERROR) << "Error getting attestation key";
+        return {};
+    }
+
+    keymaster_error_t error;
+    ::keymaster::CertChainPtr cert_chain_out;
+    ::keymaster::PureSoftKeymasterContext context;
+
+    // set identity version to 10 per hal requirements specified in IWriteableCredential.hal
+    // For now, the identity version in the attestation is set in the keymaster
+    // version field in the portable keymaster lib, which is a bit misleading.
+    uint identity_version = 10;
+    error = generate_attestation_from_EVP(key, swEnforced, hwEnforced, auth_set, context,
+                                          identity_version, *attestation_chain,
+                                          *attestation_signing_key, &cert_chain_out);
+
+    if (KM_ERROR_OK != error || !cert_chain_out) {
+        LOG(ERROR) << "Error generate attestation from EVP key" << error;
+        return {};
+    }
+
+    // translate certificate format from keymaster_cert_chain_t to vector<uint8_t>.
+    vector<vector<uint8_t>> attestationCertificate;
+    for (int i = 0; i < cert_chain_out->entry_count; i++) {
+        attestationCertificate.insert(
+                attestationCertificate.end(),
+                vector<uint8_t>(
+                        cert_chain_out->entries[i].data,
+                        cert_chain_out->entries[i].data + cert_chain_out->entries[i].data_length));
+    }
+
+    return attestationCertificate;
+}
+
+optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
+        const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) {
+    auto ec_key = ::keymaster::EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = ::keymaster::EVP_PKEY_Ptr(EVP_PKEY_new());
+    auto group = ::keymaster::EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+
+    if (ec_key.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+
+    if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
+        EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
+        LOG(ERROR) << "Error generating key";
+        return {};
+    }
+
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
+        LOG(ERROR) << "Error getting private key";
+        return {};
+    }
+
+    uint64_t now = time(nullptr);
+    uint64_t secondsInOneYear = 365 * 24 * 60 * 60;
+    uint64_t expireTimeMs = (now + secondsInOneYear) * 1000;
+
+    optional<vector<vector<uint8_t>>> attestationCert =
+            createAttestation(pkey.get(), applicationId, challenge, now * 1000, expireTimeMs);
+    if (!attestationCert) {
+        LOG(ERROR) << "Error create attestation from key and challenge";
+        return {};
+    }
+
+    int size = i2d_PrivateKey(pkey.get(), nullptr);
+    if (size == 0) {
+        LOG(ERROR) << "Error generating public key encoding";
+        return {};
+    }
+
+    vector<uint8_t> keyPair(size);
+    unsigned char* p = keyPair.data();
+    i2d_PrivateKey(pkey.get(), &p);
+
+    return make_pair(keyPair, attestationCert.value());
+}
+
 optional<vector<uint8_t>> createEcKeyPair() {
     auto ec_key = EC_KEY_Ptr(EC_KEY_new());
     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
diff --git a/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
index 6c186f6..40eb142 100644
--- a/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
+++ b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
@@ -101,6 +101,7 @@
 DECLARE_KM_4_1_TYPED_TAG(EARLY_BOOT_ONLY);
 DECLARE_KM_4_1_TYPED_TAG(DEVICE_UNIQUE_ATTESTATION);
 DECLARE_KM_4_1_TYPED_TAG(STORAGE_KEY);
+DECLARE_KM_4_1_TYPED_TAG(IDENTITY_CREDENTIAL_KEY);
 
 }  // namespace android::hardware::keymaster::V4_1
 
diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal
index daaf22e..25ec915 100644
--- a/neuralnetworks/1.3/types.hal
+++ b/neuralnetworks/1.3/types.hal
@@ -5168,6 +5168,8 @@
      * * {@link OperandType::TENSOR_FLOAT16}
      * * {@link OperandType::TENSOR_FLOAT32}
      *
+     * Supported tensor rank: from 1.
+     *
      * Inputs:
      * * 0: A tensor, specifying the input. May be zero-sized.
      * * 1: A scalar, specifying the alpha parameter.
@@ -5197,6 +5199,8 @@
      * * {@link OperandType::TENSOR_QUANT8_ASYMM}
      * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
      *
+     * Supported tensor rank: from 1.
+     *
      * Inputs:
      * * 0: A tensor, specifying the input. May be zero-sized.
      *
@@ -5215,6 +5219,8 @@
      * * {@link OperandType::TENSOR_FLOAT32}
      * * {@link OperandType::TENSOR_INT32}
      *
+     * Supported tensor rank: from 1.
+     *
      * Inputs:
      * * 0: A 1-D tensor, specifying the desired output tensor shape.
      * * 1: A scalar, specifying the value to fill the output tensors with.
@@ -5248,6 +5254,8 @@
      * * {@link OperandType::TENSOR_QUANT8_SYMM}
      * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
      *
+     * Supported tensor rank: from 1.
+     *
      * Inputs:
      * * 0: The input tensor.
      *
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index d04cb36..9b6cc96 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -578,7 +578,7 @@
 TEST_P(RadioHidlTest, nvResetConfig) {
     serial = GetRandomSerialNumber();
 
-    radio->nvResetConfig(serial, ResetNvType::ERASE);
+    radio->nvResetConfig(serial, ResetNvType::FACTORY_RESET);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
diff --git a/rebootescrow/aidl/default/HadamardUtils.cpp b/rebootescrow/aidl/default/HadamardUtils.cpp
index d2422b9..adb2010 100644
--- a/rebootescrow/aidl/default/HadamardUtils.cpp
+++ b/rebootescrow/aidl/default/HadamardUtils.cpp
@@ -16,8 +16,6 @@
 
 #include <HadamardUtils.h>
 
-#include <limits>
-
 #include <android-base/logging.h>
 
 namespace aidl {
@@ -92,6 +90,31 @@
     return result;
 }
 
+// Constant-time conditional copy, to fix b/146520538
+// ctl must be 0 or 1; we do the copy if it's 1.
+static void CondCopy(uint32_t ctl, void* dest, const void* src, size_t len) {
+    const auto cdest = reinterpret_cast<uint8_t*>(dest);
+    const auto csrc = reinterpret_cast<const uint8_t*>(src);
+    for (size_t i = 0; i < len; i++) {
+        const uint32_t d = cdest[i];
+        const uint32_t s = csrc[i];
+        cdest[i] = d ^ (-ctl & (s ^ d));
+    }
+}
+
+struct CodewordWinner {
+    uint16_t codeword;
+    int32_t score;
+};
+
+// Replace dest with src if it has a higher score
+static void CopyWinner(CodewordWinner* dest, const CodewordWinner& src) {
+    // Scores are between - 2^15 and 2^15, so taking the difference won't
+    // overflow; we use the sign bit of the difference here.
+    CondCopy(static_cast<uint32_t>(dest->score - src.score) >> 31, dest, &src,
+             sizeof(CodewordWinner));
+}
+
 // Decode a single codeword. Because of the way codewords are striped together
 // this takes the entire input, plus an offset telling it which word to decode.
 static uint16_t DecodeWord(size_t word, const std::vector<uint8_t>& encoded) {
@@ -118,20 +141,15 @@
             }
         }
     }
-    auto hiscore = std::numeric_limits<int32_t>::min();
-    uint16_t winner;
-    // TODO(b/146520538): this needs to be constant time
+    // -ENCODE_LENGTH is least possible score, so start one less than that
+    auto best = CodewordWinner{0, -static_cast<int32_t>(ENCODE_LENGTH + 1)};
+    // For every possible codeword value, look at its score, and replace best if it's higher,
+    // in constant time.
     for (size_t i = 0; i < ENCODE_LENGTH; i++) {
-        if (scores[i] > hiscore) {
-            winner = i;
-            hiscore = scores[i];
-
-        } else if (-scores[i] > hiscore) {
-            winner = i | (1 << CODE_K);
-            hiscore = -scores[i];
-        }
+        CopyWinner(&best, CodewordWinner{static_cast<uint16_t>(i), scores[i]});
+        CopyWinner(&best, CodewordWinner{static_cast<uint16_t>(i | (1 << CODE_K)), -scores[i]});
     }
-    return winner;
+    return best.codeword;
 }
 
 std::vector<uint8_t> DecodeKey(const std::vector<uint8_t>& shuffled) {
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
index 84556b5..406a899 100644
--- a/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
@@ -23,6 +23,9 @@
     /* Period of silence preceding primitive. */
     int delayMs;
     CompositePrimitive primitive;
-    /* 0.0 (exclusive) - 1.0 (inclusive) */
+    /*
+     * 0.0 (inclusive) - 1.0 (inclusive),
+     * where 0.0 is minimum "feelable" amplitude.
+     */
     float scale;
 }
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
index 0fdfa5d..8e82db0 100644
--- a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
@@ -21,37 +21,53 @@
 enum CompositePrimitive {
     /**
      * No haptic effect. Used to generate extended delays between primitives.
+     *
+     * Support is required.
      */
     NOOP,
     /**
      * This effect should produce a sharp, crisp click sensation.
+     *
+     * Support is required.
      */
     CLICK,
     /**
      * A haptic effect that simulates downwards movement with gravity. Often
      * followed by extra energy of hitting and reverberation to augment
      * physicality.
+     *
+     * Support is optional.
      */
     THUD,
     /**
      * A haptic effect that simulates spinning momentum.
+     *
+     * Support is optional.
      */
     SPIN,
     /**
      * A haptic effect that simulates quick upward movement against gravity.
+     *
+     * Support is required.
      */
     QUICK_RISE,
     /**
      * A haptic effect that simulates slow upward movement against gravity.
+     *
+     * Support is required.
      */
     SLOW_RISE,
     /**
      * A haptic effect that simulates quick downwards movement with gravity.
+     *
+     * Support is required.
      */
     QUICK_FALL,
     /**
      * This very short effect should produce a light crisp sensation intended
      * to be used repetitively for dynamic feedback.
+     *
+     * Support is required.
      */
     LIGHT_TICK,
 }
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
index 6489c1d..0b21248 100644
--- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
@@ -161,8 +161,8 @@
      * List of supported effect primitive.
      *
      * Return the effect primitives which are supported by the compose API.
-     * Implementations are expected to support all primitives of the interface
-     * version that they implement.
+     * Implementations are expected to support all required primitives of the
+     * interface version that they implement (see primitive definitions).
      */
     CompositePrimitive[] getSupportedPrimitives();
 
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index 9236b95..b359100 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -146,7 +146,7 @@
         if (e.delayMs > kComposeDelayMaxMs) {
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
-        if (e.scale <= 0.0f || e.scale > 1.0f) {
+        if (e.scale < 0.0f || e.scale > 1.0f) {
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
         if (std::find(supported.begin(), supported.end(), e.primitive) == supported.end()) {
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 411fe7a..8340517 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -21,6 +21,7 @@
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 
+#include <cmath>
 #include <future>
 
 using android::ProcessState;
@@ -53,6 +54,11 @@
         android::enum_range<CompositePrimitive>().begin(),
         android::enum_range<CompositePrimitive>().end()};
 
+const std::vector<CompositePrimitive> kOptionalPrimitives = {
+        CompositePrimitive::THUD,
+        CompositePrimitive::SPIN,
+};
+
 const std::vector<CompositePrimitive> kInvalidPrimitives = {
         static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
         static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
@@ -128,7 +134,6 @@
             } else {
                 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
                         << toString(effect) << " " << toString(strength);
-                EXPECT_EQ(lengthMs, 0);
             }
         }
     }
@@ -157,7 +162,6 @@
                 EXPECT_GT(lengthMs, 0);
             } else {
                 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
-                EXPECT_EQ(lengthMs, 0);
             }
 
             if (!status.isOk()) continue;
@@ -177,7 +181,6 @@
             int lengthMs;
             Status status = vibrator->perform(effect, strength, callback, &lengthMs);
             EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
-            EXPECT_EQ(lengthMs, 0);
         }
     }
 }
@@ -267,38 +270,56 @@
 
         EXPECT_EQ(Status::EX_NONE, vibrator->getSupportedPrimitives(&supported).exceptionCode());
 
-        std::sort(supported.begin(), supported.end());
+        for (auto primitive : kCompositePrimitives) {
+            bool isPrimitiveSupported =
+                    std::find(supported.begin(), supported.end(), primitive) != supported.end();
+            bool isPrimitiveOptional =
+                    std::find(kOptionalPrimitives.begin(), kOptionalPrimitives.end(), primitive) !=
+                    kOptionalPrimitives.end();
 
-        EXPECT_EQ(kCompositePrimitives, supported);
+            EXPECT_TRUE(isPrimitiveSupported || isPrimitiveOptional) << toString(primitive);
+        }
     }
 }
 
 TEST_P(VibratorAidl, GetPrimitiveDuration) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
-        int32_t duration;
+        std::vector<CompositePrimitive> supported;
+        ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
 
         for (auto primitive : kCompositePrimitives) {
-            EXPECT_EQ(Status::EX_NONE,
-                      vibrator->getPrimitiveDuration(primitive, &duration).exceptionCode());
+            bool isPrimitiveSupported =
+                    std::find(supported.begin(), supported.end(), primitive) != supported.end();
+            int32_t duration;
+
+            Status status = vibrator->getPrimitiveDuration(primitive, &duration);
+
+            if (isPrimitiveSupported) {
+                EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
+            } else {
+                EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
+            }
         }
     }
 }
 
 TEST_P(VibratorAidl, ComposeValidPrimitives) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+        std::vector<CompositePrimitive> supported;
         int32_t maxDelay, maxSize;
 
+        ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
         EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
         EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
 
         std::vector<CompositeEffect> composite;
 
-        for (auto primitive : kCompositePrimitives) {
+        for (auto primitive : supported) {
             CompositeEffect effect;
 
             effect.delayMs = std::rand() % (maxDelay + 1);
             effect.primitive = primitive;
-            effect.scale = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
+            effect.scale = static_cast<float>(std::rand()) / RAND_MAX;
             composite.emplace_back(effect);
 
             if (composite.size() == maxSize) {
@@ -317,7 +338,21 @@
 
 TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
-        for (auto primitive : kInvalidPrimitives) {
+        auto unsupported = kInvalidPrimitives;
+        std::vector<CompositePrimitive> supported;
+
+        ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
+
+        for (auto primitive : kCompositePrimitives) {
+            bool isPrimitiveSupported =
+                    std::find(supported.begin(), supported.end(), primitive) != supported.end();
+
+            if (!isPrimitiveSupported) {
+                unsupported.push_back(primitive);
+            }
+        }
+
+        for (auto primitive : unsupported) {
             std::vector<CompositeEffect> composite(1);
 
             for (auto& effect : composite) {
@@ -332,7 +367,33 @@
     }
 }
 
-TEST_P(VibratorAidl, CompseDelayBoundary) {
+TEST_P(VibratorAidl, ComposeScaleBoundary) {
+    if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+        std::vector<CompositeEffect> composite(1);
+        CompositeEffect& effect = composite[0];
+
+        effect.delayMs = 0;
+        effect.primitive = CompositePrimitive::CLICK;
+
+        effect.scale = std::nextafter(0.0f, -1.0f);
+        EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+                  vibrator->compose(composite, nullptr).exceptionCode());
+
+        effect.scale = 0.0f;
+        EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+        effect.scale = 1.0f;
+        EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+        effect.scale = std::nextafter(1.0f, 2.0f);
+        EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+                  vibrator->compose(composite, nullptr).exceptionCode());
+
+        vibrator->off();
+    }
+}
+
+TEST_P(VibratorAidl, ComposeDelayBoundary) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
         int32_t maxDelay;
 
@@ -357,7 +418,7 @@
     }
 }
 
-TEST_P(VibratorAidl, CompseSizeBoundary) {
+TEST_P(VibratorAidl, ComposeSizeBoundary) {
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
         int32_t maxSize;