Merge "Convert VtsHalRadioV1_5TargetTest to parameterized gtest" into rvc-dev
diff --git a/audio/6.0/Android.bp b/audio/6.0/Android.bp
index dc6bb98..16abc52 100644
--- a/audio/6.0/Android.bp
+++ b/audio/6.0/Android.bp
@@ -15,6 +15,7 @@
         "IStreamIn.hal",
         "IStreamOut.hal",
         "IStreamOutCallback.hal",
+        "IStreamOutEventCallback.hal",
     ],
     interfaces: [
         "android.hardware.audio.common@6.0",
diff --git a/audio/6.0/IStreamOut.hal b/audio/6.0/IStreamOut.hal
index 13a86ec..9da48fe 100644
--- a/audio/6.0/IStreamOut.hal
+++ b/audio/6.0/IStreamOut.hal
@@ -19,6 +19,7 @@
 import android.hardware.audio.common@6.0;
 import IStream;
 import IStreamOutCallback;
+import IStreamOutEventCallback;
 
 interface IStreamOut extends IStream {
     /**
@@ -168,6 +169,18 @@
     clearCallback() generates (Result retval);
 
     /**
+     * Set the callback interface for notifying about an output stream event.
+     *
+     * Calling this method with a null pointer will result in releasing
+     * the local callback proxy on the server side and thus dereference
+     * the callback implementation on the client side.
+     *
+     * @return retval operation completion status.
+     */
+    setEventCallback(IStreamOutEventCallback callback)
+            generates (Result retval);
+
+    /**
      * Returns whether HAL supports pausing and resuming of streams.
      *
      * @return supportsPause true if pausing is supported.
diff --git a/audio/6.0/IStreamOutEventCallback.hal b/audio/6.0/IStreamOutEventCallback.hal
new file mode 100644
index 0000000..de17d73
--- /dev/null
+++ b/audio/6.0/IStreamOutEventCallback.hal
@@ -0,0 +1,35 @@
+/*
+ * 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.audio@6.0;
+
+/**
+ * Asynchronous stream out event callback interface. The interface provides
+ * a way for the HAL to notify platform when there are changes, e.g. codec
+ * format change, from the lower layer.
+ */
+interface IStreamOutEventCallback {
+    /**
+     * Codec format changed.
+     *
+     * @param audioMetadata is a buffer containing decoded format changes
+     *     reported by codec. The buffer contains data that can be transformed
+     *     to audio metadata, which is a C++ object based map. See
+     *     `system/media/audio_utils/include/audio_utils/Metadata.h` for
+     *     more details.
+     */
+    oneway onCodecFormatChanged(vec<uint8_t> audioMetadata);
+};
diff --git a/audio/common/6.0/types.hal b/audio/common/6.0/types.hal
index b2806c7..67217ab 100644
--- a/audio/common/6.0/types.hal
+++ b/audio/common/6.0/types.hal
@@ -903,6 +903,25 @@
     SONIFICATION = 4,
 };
 
+/** Encapsulation mode used for sending audio compressed data. */
+@export(name="audio_encapsulation_mode_t", value_prefix="AUDIO_ENCAPSULATION_MODE_")
+enum AudioEncapsulationMode : int32_t {
+    // Do not change these values without updating their counterparts
+    // in frameworks/base/media/java/android/media/AudioTrack.java
+    /**
+     * No encapsulation mode for metadata.
+     */
+    NONE              = 0,
+    /**
+     * Elementary stream payload with metadata
+     */
+    ELEMENTARY_STREAM = 1,
+    /**
+     *  Handle-based payload with metadata
+     */
+    HANDLE            = 2,
+};
+
 /**
  * Additional information about the stream passed to hardware decoders.
  */
@@ -918,6 +937,9 @@
     uint32_t bitWidth;
     uint32_t bufferSize;
     AudioUsage usage;
+    AudioEncapsulationMode encapsulationMode;
+    int32_t contentId;
+    int32_t syncId;
 };
 
 /**
diff --git a/audio/common/all-versions/default/HidlUtils.cpp b/audio/common/all-versions/default/HidlUtils.cpp
index 08002c8..a470c9c 100644
--- a/audio/common/all-versions/default/HidlUtils.cpp
+++ b/audio/common/all-versions/default/HidlUtils.cpp
@@ -28,12 +28,13 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-void HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) {
+status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) {
     config->sampleRateHz = halConfig.sample_rate;
     config->channelMask = EnumBitfield<AudioChannelMask>(halConfig.channel_mask);
     config->format = AudioFormat(halConfig.format);
-    audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo);
+    status_t status = audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo);
     config->frameCount = halConfig.frame_count;
+    return status;
 }
 
 void HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) {
@@ -106,8 +107,8 @@
     return static_cast<audio_usage_t>(usage);
 }
 
-void HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
-                                        AudioOffloadInfo* offload) {
+status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
+                                            AudioOffloadInfo* offload) {
     offload->sampleRateHz = halOffload.sample_rate;
     offload->channelMask = EnumBitfield<AudioChannelMask>(halOffload.channel_mask);
     offload->format = AudioFormat(halOffload.format);
@@ -119,6 +120,26 @@
     offload->bitWidth = halOffload.bit_width;
     offload->bufferSize = halOffload.offload_buffer_size;
     offload->usage = audioUsageFromHal(halOffload.usage);
+#if MAJOR_VERSION >= 6
+    if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) {
+        offload->encapsulationMode =
+                static_cast<AudioEncapsulationMode>(halOffload.encapsulation_mode);
+        offload->contentId = halOffload.content_id;
+        offload->syncId = halOffload.sync_id;
+    } else {
+        offload->encapsulationMode = AudioEncapsulationMode::NONE;
+        offload->contentId = 0;
+        offload->syncId = 0;
+    }
+#else
+    // nonzero values here are not compatible with HAL versions below 6.
+    if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2 &&
+        (halOffload.encapsulation_mode != AUDIO_ENCAPSULATION_MODE_NONE ||
+         halOffload.content_id != 0 || halOffload.sync_id != 0)) {
+        return BAD_VALUE;
+    }
+#endif
+    return OK;
 }
 
 void HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload,
@@ -135,6 +156,14 @@
     halOffload->bit_width = offload.bitWidth;
     halOffload->offload_buffer_size = offload.bufferSize;
     halOffload->usage = audioUsageToHal(offload.usage);
+#if MAJOR_VERSION >= 6
+    halOffload->encapsulation_mode =
+            static_cast<audio_encapsulation_mode_t>(offload.encapsulationMode);
+    halOffload->content_id = offload.contentId;
+    halOffload->sync_id = offload.syncId;
+#else
+    // offload doesn't contain encapsulationMode, contentId, syncId, so this is OK.
+#endif
 }
 
 void HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig,
diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h
index 758a7f4..ef6dee3 100644
--- a/audio/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/HidlUtils.h
@@ -35,8 +35,11 @@
 using namespace ::android::hardware::audio::common::CPP_VERSION;
 
 class HidlUtils {
-   public:
-    static void audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config);
+  public:
+    // A failure here indicates a platform config that is incompatible with
+    // the compiled HIDL interface version.
+    static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config);
+
     static void audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig);
     static void audioGainConfigFromHal(const struct audio_gain_config& halConfig,
                                        AudioGainConfig* config);
@@ -46,8 +49,10 @@
     static void audioGainToHal(const AudioGain& gain, struct audio_gain* halGain);
     static AudioUsage audioUsageFromHal(const audio_usage_t halUsage);
     static audio_usage_t audioUsageToHal(const AudioUsage usage);
-    static void audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
-                                        AudioOffloadInfo* offload);
+    // A failure here indicates a platform offload info that is incompatible with
+    // the compiled HIDL interface version.
+    static status_t audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
+                                            AudioOffloadInfo* offload);
     static void audioOffloadInfoToHal(const AudioOffloadInfo& offload,
                                       audio_offload_info_t* halOffload);
     static void audioPortConfigFromHal(const struct audio_port_config& halConfig,
@@ -58,7 +63,7 @@
                                         const struct audio_port_config* halConfigs,
                                         hidl_vec<AudioPortConfig>* configs);
     static std::unique_ptr<audio_port_config[]> audioPortConfigsToHal(
-        const hidl_vec<AudioPortConfig>& configs);
+            const hidl_vec<AudioPortConfig>& configs);
     static void audioPortFromHal(const struct audio_port& halPort, AudioPort* port);
     static void audioPortToHal(const AudioPort& port, struct audio_port* halPort);
     static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid);
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 47e31c1..6260ba1 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -171,7 +171,8 @@
         streamOut = new StreamOut(this, halStream);
         ++mOpenedStreamsCount;
     }
-    HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+    status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+    ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
     return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
 }
 
@@ -198,7 +199,8 @@
         streamIn = new StreamIn(this, halStream);
         ++mOpenedStreamsCount;
     }
-    HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+    status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+    ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
     return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
 }
 
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index 7a4d72b..150d641 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -22,6 +22,8 @@
 //#define LOG_NDEBUG 0
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 
+#include <string.h>
+
 #include <memory>
 
 #include <android/log.h>
@@ -612,6 +614,33 @@
     return Result::NOT_SUPPORTED;
 }
 
+Return<Result> StreamOut::setEventCallback(const sp<IStreamOutEventCallback>& callback) {
+    if (mStream->set_event_callback == nullptr) return Result::NOT_SUPPORTED;
+    int result = mStream->set_event_callback(mStream, StreamOut::asyncEventCallback, this);
+    if (result == 0) {
+        mEventCallback = callback;
+    }
+    return Stream::analyzeStatus("set_stream_out_callback", result, {ENOSYS} /*ignore*/);
+}
+
+// static
+int StreamOut::asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie) {
+    StreamOut* self = reinterpret_cast<StreamOut*>(cookie);
+    sp<IStreamOutEventCallback> eventCallback = self->mEventCallback;
+    if (eventCallback.get() == nullptr) return 0;
+    ALOGV("%s event %d", __func__, event);
+    switch (event) {
+        case STREAM_EVENT_CBK_TYPE_CODEC_FORMAT_CHANGED: {
+            hidl_vec<uint8_t> audioMetadata;
+            audioMetadata.setToExternal((uint8_t*)param, strlen((char*)param));
+            eventCallback->onCodecFormatChanged(audioMetadata);
+        } break;
+        default:
+            ALOGW("%s unknown event %d", __func__, event);
+            break;
+    }
+    return 0;
+}
 #endif
 
 }  // namespace implementation
diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h
index 5db8626..e647da9 100644
--- a/audio/core/all-versions/default/include/core/default/StreamOut.h
+++ b/audio/core/all-versions/default/include/core/default/StreamOut.h
@@ -133,12 +133,19 @@
     static Result getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames,
                                               TimeSpec* timeStamp);
 
-   private:
+#if MAJOR_VERSION >= 6
+    Return<Result> setEventCallback(const sp<IStreamOutEventCallback>& callback) override;
+#endif
+
+  private:
     const sp<Device> mDevice;
     audio_stream_out_t* mStream;
     const sp<Stream> mStreamCommon;
     const sp<StreamMmap<audio_stream_out_t>> mStreamMmap;
-    sp<IStreamOutCallback> mCallback;
+    sp<IStreamOutCallback> mCallback;  // Callback for non-blocking write and drain
+#if MAJOR_VERSION >= 6
+    sp<IStreamOutEventCallback> mEventCallback;
+#endif
     std::unique_ptr<CommandMQ> mCommandMQ;
     std::unique_ptr<DataMQ> mDataMQ;
     std::unique_ptr<StatusMQ> mStatusMQ;
@@ -149,6 +156,10 @@
     virtual ~StreamOut();
 
     static int asyncCallback(stream_callback_event_t event, void* param, void* cookie);
+
+#if MAJOR_VERSION >= 6
+    static int asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie);
+#endif
 };
 
 }  // namespace implementation
diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
index 9e2a050..b40a329 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -251,3 +251,21 @@
 INSTANTIATE_TEST_CASE_P(PlaybackRateParametersHidl, PlaybackRateParametersHidlTest,
                         ::testing::ValuesIn(getOutputDeviceConfigParameters()),
                         &DeviceConfigParameterToString);
+
+/** Stub implementation of IStreamOutEventCallback **/
+class MockOutEventCallbacks : public IStreamOutEventCallback {
+    Return<void> onCodecFormatChanged(const hidl_vec<uint8_t>& audioMetadata __unused) override {
+        return {};
+    }
+};
+
+TEST_P(OutputStreamTest, SetEventCallback) {
+    doc::test("If supported, set event callback for output stream should never fail");
+    auto res = stream->setEventCallback(new MockOutEventCallbacks);
+    EXPECT_RESULT(okOrNotSupported, res);
+    if (res == Result::OK) {
+        ASSERT_OK(stream->setEventCallback(nullptr));
+    } else {
+        doc::partialTest("The stream does not support event callback");
+    }
+}
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
index cdea8b6..a8e7c0b 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
@@ -14,22 +14,20 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 #include <android-base/strings.h>
 #include <android/hardware/automotive/can/1.0/ICanBus.h>
 #include <android/hardware/automotive/can/1.0/types.h>
 #include <can-vts-utils/can-hal-printers.h>
-#include <can-vts-utils/environment-utils.h>
 #include <gmock/gmock.h>
 #include <hidl-utils/hidl-utils.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 namespace android::hardware::automotive::can::V1_0::vts {
 
 using hardware::hidl_vec;
 
-static utils::SimpleHidlEnvironment<ICanBus>* gEnv = nullptr;
-
 struct CanMessageListener : public can::V1_0::ICanMessageListener {
     virtual Return<void> onReceive(const can::V1_0::CanMessage&) override { return {}; }
 };
@@ -38,7 +36,7 @@
     virtual Return<void> onError(ErrorEvent, bool) override { return {}; }
 };
 
-class CanBusHalTest : public ::testing::VtsHalHidlTargetTestBase {
+class CanBusHalTest : public ::testing::TestWithParam<std::string> {
   protected:
     virtual void SetUp() override;
     virtual void TearDown() override;
@@ -51,9 +49,8 @@
 };
 
 void CanBusHalTest::SetUp() {
-    const auto serviceName = gEnv->getServiceName<ICanBus>();
-    mCanBus = getService<ICanBus>(serviceName);
-    ASSERT_TRUE(mCanBus) << "Couldn't open CAN Bus: " << serviceName;
+    mCanBus = ICanBus::getService(GetParam());
+    ASSERT_TRUE(mCanBus) << "Couldn't open CAN Bus: " << GetParam();
 }
 
 void CanBusHalTest::TearDown() {
@@ -75,7 +72,7 @@
     return res;
 }
 
-TEST_F(CanBusHalTest, SendNoPayload) {
+TEST_P(CanBusHalTest, SendNoPayload) {
     CanMessage msg = {};
     msg.id = 0x123;
     ASSERT_NE(mCanBus, nullptr);
@@ -83,7 +80,7 @@
     ASSERT_EQ(Result::OK, result);
 }
 
-TEST_F(CanBusHalTest, Send8B) {
+TEST_P(CanBusHalTest, Send8B) {
     CanMessage msg = {};
     msg.id = 0x234;
     msg.payload = {1, 2, 3, 4, 5, 6, 7, 8};
@@ -92,7 +89,7 @@
     ASSERT_EQ(Result::OK, result);
 }
 
-TEST_F(CanBusHalTest, SendZeroId) {
+TEST_P(CanBusHalTest, SendZeroId) {
     CanMessage msg = {};
     msg.payload = {1, 2, 3};
 
@@ -100,7 +97,7 @@
     ASSERT_EQ(Result::OK, result);
 }
 
-TEST_F(CanBusHalTest, SendTooLong) {
+TEST_P(CanBusHalTest, SendTooLong) {
     CanMessage msg = {};
     msg.id = 0x123;
     msg.payload = hidl_vec<uint8_t>(102400);  // 100kiB
@@ -109,14 +106,14 @@
     ASSERT_EQ(Result::PAYLOAD_TOO_LONG, result);
 }
 
-TEST_F(CanBusHalTest, ListenNoFilter) {
+TEST_P(CanBusHalTest, ListenNoFilter) {
     const auto [result, closeHandle] = listen({}, new CanMessageListener());
     ASSERT_EQ(Result::OK, result);
 
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, ListenSomeFilter) {
+TEST_P(CanBusHalTest, ListenSomeFilter) {
     hidl_vec<CanMessageFilter> filters = {
             {0x123, 0x1FF, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE, false},
             {0x001, 0x00F, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE, true},
@@ -129,12 +126,12 @@
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, ListenNull) {
+TEST_P(CanBusHalTest, ListenNull) {
     const auto [result, closeHandle] = listen({}, nullptr);
     ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
 }
 
-TEST_F(CanBusHalTest, DoubleCloseListener) {
+TEST_P(CanBusHalTest, DoubleCloseListener) {
     const auto [result, closeHandle] = listen({}, new CanMessageListener());
     ASSERT_EQ(Result::OK, result);
 
@@ -142,12 +139,12 @@
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, DontCloseListener) {
+TEST_P(CanBusHalTest, DontCloseListener) {
     const auto [result, closeHandle] = listen({}, new CanMessageListener());
     ASSERT_EQ(Result::OK, result);
 }
 
-TEST_F(CanBusHalTest, DoubleCloseErrorListener) {
+TEST_P(CanBusHalTest, DoubleCloseErrorListener) {
     auto closeHandle = listenForErrors(new CanErrorListener());
     ASSERT_NE(nullptr, closeHandle.get());
 
@@ -155,7 +152,7 @@
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, DoubleCloseNullErrorListener) {
+TEST_P(CanBusHalTest, DoubleCloseNullErrorListener) {
     auto closeHandle = listenForErrors(nullptr);
     ASSERT_NE(nullptr, closeHandle.get());
 
@@ -163,13 +160,11 @@
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, DontCloseErrorListener) {
+TEST_P(CanBusHalTest, DontCloseErrorListener) {
     auto closeHandle = listenForErrors(new CanErrorListener());
     ASSERT_NE(nullptr, closeHandle.get());
 }
 
-}  // namespace android::hardware::automotive::can::V1_0::vts
-
 /**
  * This test requires that you bring up a valid bus first.
  *
@@ -177,19 +172,12 @@
  * mma -j && adb root && adb remount && adb sync
  *
  * Example manual invocation:
- * adb shell /data/nativetest64/VtsHalCanBusV1_0TargetTest/VtsHalCanBusV1_0TargetTest \
- *     --hal_service_instance=android.hardware.automotive.can@1.0::ICanBus/<NAME_OF_VALID_BUS>
+ * adb shell canhalctrl up <NAME_OF_VALID_BUS> socketcan can0 125000
+ * adb shell /data/nativetest64/VtsHalCanBusV1_0TargetTest/VtsHalCanBusV1_0TargetTest\
+ *     --gtest_filter=*_<NAME_OF_VALID_BUS>
  */
-int main(int argc, char** argv) {
-    using android::hardware::automotive::can::V1_0::ICanBus;
-    using android::hardware::automotive::can::V1_0::vts::gEnv;
-    using android::hardware::automotive::can::V1_0::vts::utils::SimpleHidlEnvironment;
-    setenv("TREBLE_TESTING_OVERRIDE", "true", true);
-    android::base::SetDefaultTag("CanBusVts");
-    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
-    gEnv = new SimpleHidlEnvironment<ICanBus>;
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    return RUN_ALL_TESTS();
-}
+INSTANTIATE_TEST_SUITE_P(  //
+        PerInstance, CanBusHalTest, testing::ValuesIn(getAllHalInstanceNames(ICanBus::descriptor)),
+        PrintInstanceNameToString);
+
+}  // namespace android::hardware::automotive::can::V1_0::vts
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
index 68d555d..9039435 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 #include <android-base/strings.h>
 #include <android/hardware/automotive/can/1.0/ICanBus.h>
@@ -23,9 +22,11 @@
 #include <android/hidl/manager/1.2/IServiceManager.h>
 #include <can-vts-utils/bus-enumerator.h>
 #include <can-vts-utils/can-hal-printers.h>
-#include <can-vts-utils/environment-utils.h>
 #include <gmock/gmock.h>
+#include <gtest/gtest.h>
 #include <hidl-utils/hidl-utils.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 #include <utils/Mutex.h>
 #include <utils/SystemClock.h>
 
@@ -39,8 +40,6 @@
 using hardware::hidl_vec;
 using InterfaceType = ICanController::InterfaceType;
 
-static utils::SimpleHidlEnvironment<ICanController>* gEnv = nullptr;
-
 struct CanMessageListener : public can::V1_0::ICanMessageListener {
     DISALLOW_COPY_AND_ASSIGN(CanMessageListener);
 
@@ -133,12 +132,11 @@
     sp<ICanBus> mBus;
 };
 
-class CanBusVirtualHalTest : public ::testing::VtsHalHidlTargetTestBase {
+class CanBusVirtualHalTest : public ::testing::TestWithParam<std::string> {
   protected:
     virtual void SetUp() override;
-
+    virtual void TearDown() override;
     static void SetUpTestCase();
-    static void TearDownTestCase();
 
     Bus makeBus();
 
@@ -147,13 +145,10 @@
 
   private:
     unsigned mLastIface = 0;
-    static sp<ICanController> mCanController;
-    static bool mVirtualSupported;
+    sp<ICanController> mCanController = nullptr;
     static bool mTestCaseInitialized;
 };
 
-sp<ICanController> CanBusVirtualHalTest::mCanController = nullptr;
-bool CanBusVirtualHalTest::mVirtualSupported;
 hidl_vec<hidl_string> CanBusVirtualHalTest::mBusNames;
 bool CanBusVirtualHalTest::mTestCaseInitialized = false;
 
@@ -170,29 +165,27 @@
 }
 
 void CanBusVirtualHalTest::SetUp() {
-    if (!mVirtualSupported) GTEST_SKIP();
     ASSERT_TRUE(mTestCaseInitialized);
-}
 
-void CanBusVirtualHalTest::SetUpTestCase() {
-    const auto serviceName = gEnv->getServiceName<ICanController>();
-    mCanController = getService<ICanController>(serviceName);
-    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << serviceName;
+    mCanController = ICanController::getService(GetParam());
+    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << GetParam();
 
     hidl_vec<InterfaceType> supported;
     mCanController->getSupportedInterfaceTypes(hidl_utils::fill(&supported)).assertOk();
-    mVirtualSupported = supported.contains(InterfaceType::VIRTUAL);
+    if (!supported.contains(InterfaceType::VIRTUAL)) GTEST_SKIP();
+}
 
+void CanBusVirtualHalTest::TearDown() {
+    mCanController.clear();
+}
+
+void CanBusVirtualHalTest::SetUpTestCase() {
     mBusNames = utils::getBusNames();
     ASSERT_NE(0u, mBusNames.size()) << "No ICanBus HALs defined in device manifest";
 
     mTestCaseInitialized = true;
 }
 
-void CanBusVirtualHalTest::TearDownTestCase() {
-    mCanController.clear();
-}
-
 Bus CanBusVirtualHalTest::makeBus() {
     const auto idx = mLastIface++;
     EXPECT_LT(idx, mBusNames.size());
@@ -204,7 +197,7 @@
     return Bus(mCanController, config);
 }
 
-TEST_F(CanBusVirtualHalTest, Send) {
+TEST_P(CanBusVirtualHalTest, Send) {
     auto bus = makeBus();
 
     CanMessage msg = {};
@@ -214,7 +207,7 @@
     bus.send(msg);
 }
 
-TEST_F(CanBusVirtualHalTest, SendAfterClose) {
+TEST_P(CanBusVirtualHalTest, SendAfterClose) {
     auto bus = makeBus();
     auto zombie = bus.get();
     bus.reset();
@@ -223,7 +216,7 @@
     ASSERT_EQ(Result::INTERFACE_DOWN, result);
 }
 
-TEST_F(CanBusVirtualHalTest, SendAndRecv) {
+TEST_P(CanBusVirtualHalTest, SendAndRecv) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
     auto bus1 = makeBus();
     auto bus2 = makeBus();
@@ -243,7 +236,7 @@
     ASSERT_EQ(msg, messages[0]);
 }
 
-TEST_F(CanBusVirtualHalTest, DownOneOfTwo) {
+TEST_P(CanBusVirtualHalTest, DownOneOfTwo) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
 
     auto bus1 = makeBus();
@@ -254,7 +247,7 @@
     bus1.send({});
 }
 
-TEST_F(CanBusVirtualHalTest, FilterPositive) {
+TEST_P(CanBusVirtualHalTest, FilterPositive) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
     auto bus1 = makeBus();
     auto bus2 = makeBus();
@@ -418,7 +411,7 @@
     ASSERT_EQ(expectedPositive, messagesPositive);
 }
 
-TEST_F(CanBusVirtualHalTest, FilterNegative) {
+TEST_P(CanBusVirtualHalTest, FilterNegative) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
     auto bus1 = makeBus();
     auto bus2 = makeBus();
@@ -612,7 +605,7 @@
     ASSERT_EQ(expectedNegative, messagesNegative);
 }
 
-TEST_F(CanBusVirtualHalTest, FilterMixed) {
+TEST_P(CanBusVirtualHalTest, FilterMixed) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
     auto bus1 = makeBus();
     auto bus2 = makeBus();
@@ -871,22 +864,13 @@
     ASSERT_EQ(expectedMixed, messagesMixed);
 }
 
-}  // namespace android::hardware::automotive::can::V1_0::vts
-
 /**
  * Example manual invocation:
- * adb shell /data/nativetest64/VtsHalCanBusVirtualV1_0TargetTest/VtsHalCanBusVirtualV1_0TargetTest\
- *     --hal_service_instance=android.hardware.automotive.can@1.0::ICanController/socketcan
+ * adb shell /data/nativetest64/VtsHalCanBusVirtualV1_0TargetTest/VtsHalCanBusVirtualV1_0TargetTest
  */
-int main(int argc, char** argv) {
-    using android::hardware::automotive::can::V1_0::ICanController;
-    using android::hardware::automotive::can::V1_0::vts::gEnv;
-    using android::hardware::automotive::can::V1_0::vts::utils::SimpleHidlEnvironment;
-    android::base::SetDefaultTag("CanBusVirtualVts");
-    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
-    gEnv = new SimpleHidlEnvironment<ICanController>;
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    return RUN_ALL_TESTS();
-}
+INSTANTIATE_TEST_SUITE_P(  //
+        PerInstance, CanBusVirtualHalTest,
+        testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)),
+        PrintInstanceNameToString);
+
+}  // namespace android::hardware::automotive::can::V1_0::vts
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
index 8397215..8ef5758 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 #include <android-base/strings.h>
 #include <android/hardware/automotive/can/1.0/ICanBus.h>
@@ -23,9 +22,10 @@
 #include <android/hidl/manager/1.2/IServiceManager.h>
 #include <can-vts-utils/bus-enumerator.h>
 #include <can-vts-utils/can-hal-printers.h>
-#include <can-vts-utils/environment-utils.h>
 #include <gmock/gmock.h>
 #include <hidl-utils/hidl-utils.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 namespace android::hardware::automotive::can::V1_0::vts {
 
@@ -33,9 +33,7 @@
 using InterfaceType = ICanController::InterfaceType;
 using IfId = ICanController::BusConfig::InterfaceId;
 
-static utils::SimpleHidlEnvironment<ICanController>* gEnv = nullptr;
-
-class CanControllerHalTest : public ::testing::VtsHalHidlTargetTestBase {
+class CanControllerHalTest : public ::testing::TestWithParam<std::string> {
   protected:
     virtual void SetUp() override;
     virtual void TearDown() override;
@@ -61,9 +59,8 @@
 void CanControllerHalTest::SetUp() {
     ASSERT_TRUE(mTestCaseInitialized);
 
-    const auto serviceName = gEnv->getServiceName<ICanController>();
-    mCanController = getService<ICanController>(serviceName);
-    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << serviceName;
+    mCanController = ICanController::getService(GetParam());
+    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << GetParam();
 }
 
 void CanControllerHalTest::TearDown() {
@@ -130,12 +127,12 @@
             << " (should be otherwise)";
 }
 
-TEST_F(CanControllerHalTest, SupportsSomething) {
+TEST_P(CanControllerHalTest, SupportsSomething) {
     const auto supported = getSupportedInterfaceTypes();
     ASSERT_GT(supported.size(), 0u);
 }
 
-TEST_F(CanControllerHalTest, BringUpDown) {
+TEST_P(CanControllerHalTest, BringUpDown) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -148,12 +145,12 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, DownDummy) {
+TEST_P(CanControllerHalTest, DownDummy) {
     const auto result = mCanController->downInterface("imnotup");
     ASSERT_FALSE(result);
 }
 
-TEST_F(CanControllerHalTest, UpTwice) {
+TEST_P(CanControllerHalTest, UpTwice) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -169,7 +166,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, ConfigCompatibility) {
+TEST_P(CanControllerHalTest, ConfigCompatibility) {
     // using random-ish addresses, which may not be valid - we can't test the success case
     // TODO(b/146214370): move interfaceId constructors to a library
     IfId virtualCfg = {};
@@ -231,7 +228,7 @@
     }
 }
 
-TEST_F(CanControllerHalTest, FailEmptyName) {
+TEST_P(CanControllerHalTest, FailEmptyName) {
     const std::string name = "";
 
     assertRegistered(name, false);
@@ -241,7 +238,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, FailBadName) {
+TEST_P(CanControllerHalTest, FailBadName) {
     // 33 characters (name can be at most 32 characters long)
     const std::string name = "ab012345678901234567890123456789c";
 
@@ -252,7 +249,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, FailBadVirtualAddress) {
+TEST_P(CanControllerHalTest, FailBadVirtualAddress) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -262,7 +259,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, FailBadSocketcanAddress) {
+TEST_P(CanControllerHalTest, FailBadSocketcanAddress) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -277,7 +274,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, FailBadSlcanAddress) {
+TEST_P(CanControllerHalTest, FailBadSlcanAddress) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -292,22 +289,13 @@
     assertRegistered(name, false);
 }
 
-}  // namespace android::hardware::automotive::can::V1_0::vts
-
 /**
  * Example manual invocation:
- * adb shell /data/nativetest64/VtsHalCanControllerV1_0TargetTest/VtsHalCanControllerV1_0TargetTest\
- *     --hal_service_instance=android.hardware.automotive.can@1.0::ICanController/socketcan
+ * adb shell /data/nativetest64/VtsHalCanControllerV1_0TargetTest/VtsHalCanControllerV1_0TargetTest
  */
-int main(int argc, char** argv) {
-    using android::hardware::automotive::can::V1_0::ICanController;
-    using android::hardware::automotive::can::V1_0::vts::gEnv;
-    using android::hardware::automotive::can::V1_0::vts::utils::SimpleHidlEnvironment;
-    android::base::SetDefaultTag("CanControllerVts");
-    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
-    gEnv = new SimpleHidlEnvironment<ICanController>;
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    return RUN_ALL_TESTS();
-}
+INSTANTIATE_TEST_SUITE_P(  //
+        PerInstance, CanControllerHalTest,
+        testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)),
+        PrintInstanceNameToString);
+
+}  // namespace android::hardware::automotive::can::V1_0::vts
diff --git a/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h b/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h
deleted file mode 100644
index 3eb9cc1..0000000
--- a/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <VtsHalHidlTargetTestEnvBase.h>
-
-namespace android::hardware::automotive::can::V1_0::vts::utils {
-
-/**
- * Simple test environment.
- *
- * This is a helper class to instantiate a test environment without boilerplate code for cases where
- * there is no need to pass more parameters than just HIDL service instance name.
- *
- * The class implements registerTestServices() by calling registerTestService() on every HIDL
- * interface provided as parameter to this template.
- *
- * Example usage:
- *     static utils::SimpleHidlEnvironment<IMyService>* gEnv = nullptr;
- *
- *     void CanBusHalTest::SetUp() {
- *         const auto serviceName = gEnv->getServiceName<IMyService>();
- *         (...)
- *     }
- *
- *     int main(int argc, char** argv) {
- *         gEnv = new SimpleHidlEnvironment<IMyService>;
- *         ::testing::AddGlobalTestEnvironment(gEnv);
- *         ::testing::InitGoogleTest(&argc, argv);
- *         gEnv->init(&argc, argv);
- *         return RUN_ALL_TESTS();
- *     }
- *
- * \param T... HIDL interface names to register for a test service
- */
-template <typename... T>
-class SimpleHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-  public:
-    virtual void registerTestServices() override {
-        // Call registerTestService() for every HIDL interface using this template.
-        using expander = int[];
-        (void)expander{0, (registerTestService<T>(), 0)...};
-    }
-};
-
-}  // namespace android::hardware::automotive::can::V1_0::vts::utils
diff --git a/current.txt b/current.txt
index e7face5..8e2016d 100644
--- a/current.txt
+++ b/current.txt
@@ -611,9 +611,10 @@
 bca5379d5065e2e08b6ad7308ffc8a71a972fc0698bec678ea32eea786d01cb5 android.hardware.audio@6.0::IPrimaryDevice
 fd1f1b29f26b42e886220f04a08086c00e5ade9d7b53f095438e578ab9d42a93 android.hardware.audio@6.0::IStream
 2df5d5866b37776f25079c0e54b54350a2abe4e025a59c9e02a7d3abe8ca00e8 android.hardware.audio@6.0::IStreamIn
-e6cd2b7c1a86b6ca683c0224ffde3b73aa14f6487de9f46833e539d26d1b3b5c android.hardware.audio@6.0::IStreamOut
+164826a380f4c1700183003f62d7532e367b67381c30ea44f946c0cf00008f85 android.hardware.audio@6.0::IStreamOut
 997fdaad7a9d17ee7e01feb7031a753e2365e72ad30b11d950e9183fabdf3844 android.hardware.audio@6.0::IStreamOutCallback
-167ed5cfb7d91db2e2bf20f1320c1a9004eeb768e26f535e0f7db94a21867d21 android.hardware.audio.common@6.0::types
+e7ca0db9a1098210f327a9b152fa6afe6bf019c41e5264c64829d04d50c0a526 android.hardware.audio@6.0::IStreamOutEventCallback
+bee662c62d997d8065e2bcb5c1e7a9578931f22ce28fd02c219fdb4d0630abf7 android.hardware.audio.common@6.0::types
 817930d58412d662cb45e641c50cb62c727e4a3e3ffe7029a53cad9677b97d58 android.hardware.audio.effect@6.0::types
 525bec6b44f1103869c269a128d51b8dccd73af5340ba863c8886c68357c7faf android.hardware.audio.effect@6.0::IAcousticEchoCancelerEffect
 8d76bbe3719d051a8e9a1dcf9244f37f5b0a491feb249fa48391edf7cb4f3131 android.hardware.audio.effect@6.0::IAutomaticGainControlEffect
@@ -702,13 +703,9 @@
 77531c8d048f8f8ae532babd0ca86332a865ec9aace1b051226ef2b21123e645 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types
 99f5c26b952271d1246c957e1d0271fa39445ee65cc93aa7c187834f98914a33 android.hardware.radio@1.5::types
-7fefa2cc5b3b3be10b5cff5c5dc195385f491d4bf23ca65f9c6b3c30c8753a33 android.hardware.radio@1.5::IRadio
+890ecacaaa6660802bac01bbbe5f16b1eb1d6a3a3f0e5b398be5cec76a5ab673 android.hardware.radio@1.5::IRadio
 e96ae1c3a9c0689002ec2318e9c587f4f607c16a75a3cd38788b77eb91072021 android.hardware.radio@1.5::IRadioIndication
 829d3827eeb5a8f563e80fe627419b3231012fc02bc2e79782ec5e9ad9f799a4 android.hardware.radio@1.5::IRadioResponse
-4c4ce691df02faa28c0729e2a033ec464e1d72699be8bcde4dfb141313dbeba8 android.hardware.radio.config@1.3::types
-a2977755bc5f1ef47f04b7f2400632efda6218e1515dba847da487145cfabc4f android.hardware.radio.config@1.3::IRadioConfig
-742360c775313438b0f82256eac62fb5bbc76a6ae6f388573f3aa142fb2c1eea android.hardware.radio.config@1.3::IRadioConfigIndication
-0006ab8e8b0910cbd3bbb08d5f17d5fac7d65a2bdad5f2334e4851db9d1e6fa8 android.hardware.radio.config@1.3::IRadioConfigResponse
 3ca6616381080bdd6c08141ad12775a94ae868c58b02b1274ae3326f7de724ab android.hardware.sensors@2.1::ISensors
 3d4141c6373cd9ca02fe221a7d12343840de2255d032c38248fe8e35816b58b2 android.hardware.sensors@2.1::ISensorsCallback
 8051cc50fc90ed447f058a8b15d81f35a65f1bd9004b1de4f127edeb89b47978 android.hardware.sensors@2.1::types
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
index 18c4a2e..ce08396 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
@@ -41,6 +41,9 @@
     /* Blue */
     B = 1 << 12,
 
+    /* Raw */
+    RAW = 1 << 20,
+
     /* Alpha */
     A = 1 << 30,
 }
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index b6343d3..7a00ed2 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -279,23 +279,48 @@
               mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos));
 }
 
-TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) {
+TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) {
     for (Display display : mComposerCallback->getDisplays()) {
         for (Config config : mComposerClient->getDisplayConfigs(display)) {
             VsyncPeriodNanos expectedVsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4(
                     display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
 
-            mComposerClient->setActiveConfig(display, config);
+            VsyncPeriodChangeTimeline timeline;
+            IComposerClient::VsyncPeriodChangeConstraints constraints;
+
+            constraints.desiredTimeNanos = systemTime();
+            constraints.seamlessRequired = false;
+            EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
+                                           display, config, constraints, &timeline));
+
+            if (timeline.refreshRequired) {
+                sendRefreshFrame(timeline);
+            }
+            waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, 0,
+                                     expectedVsyncPeriodNanos);
+
             VsyncPeriodNanos vsyncPeriodNanos;
             int retryCount = 100;
             do {
                 std::this_thread::sleep_for(10ms);
+                vsyncPeriodNanos = 0;
                 EXPECT_EQ(Error::NONE,
                           mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
                 --retryCount;
             } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
 
             EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+
+            // Make sure that the vsync period stays the same if the active config is not changed.
+            auto timeout = 1ms;
+            for (int i = 0; i < 10; i++) {
+                std::this_thread::sleep_for(timeout);
+                timeout *= 2;
+                vsyncPeriodNanos = 0;
+                EXPECT_EQ(Error::NONE,
+                          mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+                EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+            }
         }
     }
 }
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 1416fcc..295ba36 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -278,6 +278,8 @@
         }
     }
 
+    bool isEqual(float a, float b) { return abs(a - b) < 0.0001; }
+
     std::unique_ptr<Gralloc> mGralloc;
     IMapper::BufferDescriptorInfo mDummyDescriptorInfo{};
     static const std::set<StandardMetadataType> sRequiredMetadataTypes;
@@ -725,8 +727,10 @@
 
     int fence;
     ASSERT_NO_FATAL_FAILURE(fence = mGralloc->flushLockedBuffer(writeBufferHandle));
-    ASSERT_EQ(0, sync_wait(fence, 3500));
-    close(fence);
+    if (fence >= 0) {
+        ASSERT_EQ(0, sync_wait(fence, 3500));
+        close(fence);
+    }
 
     ASSERT_NO_FATAL_FAILURE(mGralloc->rereadLockedBuffer(readBufferHandle));
 
@@ -1455,17 +1459,17 @@
      *  red             0.680   0.320
      *  white (D65)     0.3127  0.3290
      */
-    std::optional<Smpte2086> smpte2086;
-    smpte2086->primaryRed.x = 0.680;
-    smpte2086->primaryRed.y = 0.320;
-    smpte2086->primaryGreen.x = 0.265;
-    smpte2086->primaryGreen.y = 0.690;
-    smpte2086->primaryBlue.x = 0.150;
-    smpte2086->primaryBlue.y = 0.060;
-    smpte2086->whitePoint.x = 0.3127;
-    smpte2086->whitePoint.y = 0.3290;
-    smpte2086->maxLuminance = 100.0;
-    smpte2086->minLuminance = 0.1;
+    Smpte2086 smpte2086;
+    smpte2086.primaryRed.x = 0.680;
+    smpte2086.primaryRed.y = 0.320;
+    smpte2086.primaryGreen.x = 0.265;
+    smpte2086.primaryGreen.y = 0.690;
+    smpte2086.primaryBlue.x = 0.150;
+    smpte2086.primaryBlue.y = 0.060;
+    smpte2086.whitePoint.x = 0.3127;
+    smpte2086.whitePoint.y = 0.3290;
+    smpte2086.maxLuminance = 100.0;
+    smpte2086.minLuminance = 0.1;
 
     hidl_vec<uint8_t> vec;
     ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2086(smpte2086, &vec));
@@ -1475,16 +1479,16 @@
                 std::optional<Smpte2086> realSmpte2086;
                 ASSERT_EQ(NO_ERROR, gralloc4::decodeSmpte2086(vec, &realSmpte2086));
                 ASSERT_TRUE(realSmpte2086.has_value());
-                EXPECT_EQ(smpte2086->primaryRed.x, realSmpte2086->primaryRed.x);
-                EXPECT_EQ(smpte2086->primaryRed.y, realSmpte2086->primaryRed.y);
-                EXPECT_EQ(smpte2086->primaryGreen.x, realSmpte2086->primaryGreen.x);
-                EXPECT_EQ(smpte2086->primaryGreen.y, realSmpte2086->primaryGreen.y);
-                EXPECT_EQ(smpte2086->primaryBlue.x, realSmpte2086->primaryBlue.x);
-                EXPECT_EQ(smpte2086->primaryBlue.y, realSmpte2086->primaryBlue.y);
-                EXPECT_EQ(smpte2086->whitePoint.x, realSmpte2086->whitePoint.x);
-                EXPECT_EQ(smpte2086->whitePoint.y, realSmpte2086->whitePoint.y);
-                EXPECT_EQ(smpte2086->maxLuminance, realSmpte2086->maxLuminance);
-                EXPECT_EQ(smpte2086->minLuminance, realSmpte2086->minLuminance);
+                EXPECT_TRUE(isEqual(smpte2086.primaryRed.x, realSmpte2086->primaryRed.x));
+                EXPECT_TRUE(isEqual(smpte2086.primaryRed.y, realSmpte2086->primaryRed.y));
+                EXPECT_TRUE(isEqual(smpte2086.primaryGreen.x, realSmpte2086->primaryGreen.x));
+                EXPECT_TRUE(isEqual(smpte2086.primaryGreen.y, realSmpte2086->primaryGreen.y));
+                EXPECT_TRUE(isEqual(smpte2086.primaryBlue.x, realSmpte2086->primaryBlue.x));
+                EXPECT_TRUE(isEqual(smpte2086.primaryBlue.y, realSmpte2086->primaryBlue.y));
+                EXPECT_TRUE(isEqual(smpte2086.whitePoint.x, realSmpte2086->whitePoint.x));
+                EXPECT_TRUE(isEqual(smpte2086.whitePoint.y, realSmpte2086->whitePoint.y));
+                EXPECT_TRUE(isEqual(smpte2086.maxLuminance, realSmpte2086->maxLuminance));
+                EXPECT_TRUE(isEqual(smpte2086.minLuminance, realSmpte2086->minLuminance));
             });
 }
 
@@ -1492,9 +1496,9 @@
  * Test IMapper::set(Cta8613)
  */
 TEST_P(GraphicsMapperHidlTest, SetCta861_3) {
-    std::optional<Cta861_3> cta861_3;
-    cta861_3->maxContentLightLevel = 78.0;
-    cta861_3->maxFrameAverageLightLevel = 62.0;
+    Cta861_3 cta861_3;
+    cta861_3.maxContentLightLevel = 78.0;
+    cta861_3.maxFrameAverageLightLevel = 62.0;
 
     hidl_vec<uint8_t> vec;
     ASSERT_EQ(NO_ERROR, gralloc4::encodeCta861_3(cta861_3, &vec));
@@ -1504,9 +1508,10 @@
                 std::optional<Cta861_3> realCta861_3;
                 ASSERT_EQ(NO_ERROR, gralloc4::decodeCta861_3(vec, &realCta861_3));
                 ASSERT_TRUE(realCta861_3.has_value());
-                EXPECT_EQ(cta861_3->maxContentLightLevel, realCta861_3->maxContentLightLevel);
-                EXPECT_EQ(cta861_3->maxFrameAverageLightLevel,
-                          realCta861_3->maxFrameAverageLightLevel);
+                EXPECT_TRUE(
+                        isEqual(cta861_3.maxContentLightLevel, realCta861_3->maxContentLightLevel));
+                EXPECT_TRUE(isEqual(cta861_3.maxFrameAverageLightLevel,
+                                    realCta861_3->maxFrameAverageLightLevel));
             });
 }
 
@@ -1990,7 +1995,7 @@
         const auto& metadataType = description.metadataType;
 
         if (!gralloc4::isStandardMetadataType(metadataType)) {
-            EXPECT_GT(0, description.description.size());
+            EXPECT_GT(description.description.size(), 0);
             continue;
         }
 
@@ -2074,7 +2079,7 @@
     auto info = mDummyDescriptorInfo;
 
     const int pageSize = getpagesize();
-    ASSERT_GE(0, pageSize);
+    ASSERT_GE(pageSize, 0);
     std::vector<uint64_t> requestedReservedSizes{1, 10, 333, static_cast<uint64_t>(pageSize) / 2,
                                                  static_cast<uint64_t>(pageSize)};
 
@@ -2106,7 +2111,7 @@
     auto info = mDummyDescriptorInfo;
 
     const int pageSize = getpagesize();
-    ASSERT_GE(0, pageSize);
+    ASSERT_GE(pageSize, 0);
     std::vector<uint64_t> requestedReservedSizes{static_cast<uint64_t>(pageSize) * 2,
                                                  static_cast<uint64_t>(pageSize) * 10,
                                                  static_cast<uint64_t>(pageSize) * 1000};
@@ -2144,7 +2149,7 @@
     auto info = mDummyDescriptorInfo;
 
     const int pageSize = getpagesize();
-    ASSERT_GE(0, pageSize);
+    ASSERT_GE(pageSize, 0);
     info.reservedSize = pageSize;
 
     ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
diff --git a/radio/1.5/IRadio.hal b/radio/1.5/IRadio.hal
index 0b50436..87824e2 100644
--- a/radio/1.5/IRadio.hal
+++ b/radio/1.5/IRadio.hal
@@ -238,7 +238,8 @@
      * 1) Emergency call is completed; or
      * 2) Another setRadioPower_1_5 is issued with forEmergencyCall being false or
      * preferredForEmergencyCall being false; or
-     * 3) Timeout after a long period of time.
+     * 3) Timeout after 30 seconds if dial or emergencyDial is not called.
+     * Once one of these conditions is reached, the modem should move into normal operation.
      *
      * @param serial Serial number of request.
      * @param powerOn To turn on radio -> on = true, to turn off radio -> on = false.