Merge changes from topic 'vts_camera_tests'

* changes:
  Camera: Check for transport errors during VTS
  Camera: Add Hal version 1 get-/setParameter tests
  Camera: Add Hal version 1 sendcommand tests
  Camera: Add Hal version 1 autofocus test cases
  Camera: Add Hal version 1 video recording test cases
  Camera: Add Hal version 1 image capture test cases
  Camera: Add device ver. 1 preview test cases
  Camera: Extend camera test cases for camera 1.0 devices
  Camera: Add flush test cases
  Camera: Enable and check for torch callbacks
diff --git a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index a339f99..e50b912 100644
--- a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -49,6 +49,7 @@
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
+using ::android::hardware::MQDescriptorSync;
 using ::android::hardware::audio::V2_0::DeviceAddress;
 using ::android::hardware::audio::V2_0::IDevice;
 using ::android::hardware::audio::V2_0::IPrimaryDevice;
@@ -56,7 +57,11 @@
 using ::android::hardware::audio::V2_0::IDevicesFactory;
 using ::android::hardware::audio::V2_0::IStream;
 using ::android::hardware::audio::V2_0::IStreamIn;
+using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
+using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
 using ::android::hardware::audio::V2_0::IStreamOut;
+using ::android::hardware::audio::V2_0::MmapBufferInfo;
+using ::android::hardware::audio::V2_0::MmapPosition;
 using ::android::hardware::audio::V2_0::ParameterValue;
 using ::android::hardware::audio::V2_0::Result;
 using ::android::hardware::audio::common::V2_0::AudioChannelMask;
@@ -70,6 +75,7 @@
 using ::android::hardware::audio::common::V2_0::AudioOffloadInfo;
 using ::android::hardware::audio::common::V2_0::AudioOutputFlag;
 using ::android::hardware::audio::common::V2_0::AudioSource;
+using ::android::hardware::audio::common::V2_0::ThreadInfo;
 
 using utility::returnIn;
 
@@ -186,60 +192,7 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
-//////////////////////////// {set,get}MasterVolume ///////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-class MasterVolumeTest : public AudioPrimaryHidlTest {
-protected:
-    void testSetGetConsistency(float volume, Result expectedSetResult, float expectedGetVolume) {
-        SCOPED_TRACE("Test set/get consistency for " + to_string(volume));
-        auto ret = device->setMasterVolume(volume);
-        ASSERT_TRUE(ret.isOk());
-        ASSERT_EQ(expectedSetResult, ret);
-
-        float observedVolume;
-        ASSERT_OK(device->getMasterVolume(returnIn(res, observedVolume)));
-        ASSERT_OK(res);
-
-        // Check that `get` returned the expected value
-        EXPECT_EQ(expectedGetVolume, observedVolume);
-    }
-};
-
-TEST_F(MasterVolumeTest, MasterVolumeTest) {
-    doc::test("Test the master volume if supported");
-    {
-        SCOPED_TRACE("Check for master volume support");
-        auto ret = device->setMasterVolume(1);
-        ASSERT_TRUE(ret.isOk());
-        if (ret == Result::NOT_SUPPORTED) {
-            doc::partialTest("Master volume is not supported");
-            return;
-        }
-    }
-    // NOTE: this code has never been tested on a platform supporting MasterVolume
-    float lastValidVolumeSet;
-    using Volumes = float[];
-    SCOPED_TRACE("As set/get master volume are supported...");
-    {
-        SCOPED_TRACE("...test them with valid values");
-        for (float validVolume : Volumes{0, 0.5, 1}) {
-            ASSERT_NO_FATAL_FAILURE(testSetGetConsistency(validVolume, Result::OK, validVolume));
-            lastValidVolumeSet = validVolume;
-        }
-    }{
-        SCOPED_TRACE("...test them with tricky values");
-        for (float outOfBoundVolume :Volumes{-0.1, 1.1, NAN, INFINITY, -INFINITY,
-                                             1 + std::numeric_limits<float>::epsilon()}) {
-        ASSERT_NO_FATAL_FAILURE(testSetGetConsistency(outOfBoundVolume,
-                                                      Result::INVALID_ARGUMENTS,
-                                                      lastValidVolumeSet));
-        }
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-////////////////////////// {set,get}{Master,Mic}Mute /////////////////////////
+///////////////////// {set,get}{Master,Mic}{Mute,Volume} /////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
 template <class Property>
@@ -249,14 +202,16 @@
     /** Test a property getter and setter. */
     template <class Getter, class Setter>
     void testAccessors(const string& propertyName, const vector<Property>& valuesToTest,
-                       Setter setter, Getter getter) {
+                       Setter setter, Getter getter,
+                       const vector<Property>& invalidValues = {}) {
 
         Property initialValue; // Save initial value to restore it at the end of the test
         ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
         ASSERT_OK(res);
 
         for (Property setValue : valuesToTest) {
-            SCOPED_TRACE("Test " + propertyName + " getter and setter for " + testing::PrintToString(setValue));
+            SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
+                         testing::PrintToString(setValue));
             ASSERT_OK((device.get()->*setter)(setValue));
             Property getValue;
             // Make sure the getter returns the same value just set
@@ -265,13 +220,20 @@
             EXPECT_EQ(setValue, getValue);
         }
 
+        for (Property invalidValue : invalidValues) {
+            SCOPED_TRACE("Try to set " + propertyName + " with the invalid value " +
+                         testing::PrintToString(invalidValue));
+            EXPECT_RESULT(Result::INVALID_ARGUMENTS, (device.get()->*setter)(invalidValue));
+        }
+
         ASSERT_OK((device.get()->*setter)(initialValue)); // restore initial value
     }
 
     /** Test the getter and setter of an optional feature. */
     template <class Getter, class Setter>
     void testOptionalAccessors(const string& propertyName, const vector<Property>& valuesToTest,
-                               Setter setter, Getter getter) {
+                               Setter setter, Getter getter,
+                               const vector<Property>& invalidValues = {}) {
         doc::test("Test the optional " + propertyName + " getters and setter");
         {
             SCOPED_TRACE("Test feature support by calling the getter");
@@ -284,7 +246,7 @@
             ASSERT_OK(res); // If it is supported it must succeed
         }
         // The feature is supported, test it
-        testAccessors(propertyName, valuesToTest, setter, getter);
+        testAccessors(propertyName, valuesToTest, setter, getter, invalidValues);
     }
 };
 
@@ -303,6 +265,39 @@
     // TODO: check that the master volume is really muted
 }
 
+using FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
+TEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
+    doc::test("Test the master volume if supported");
+    testOptionalAccessors("master volume",  {0, 0.5, 1},
+                          &IDevice::setMasterVolume, &IDevice::getMasterVolume,
+                          {-0.1, 1.1, NAN, INFINITY, -INFINITY,
+                           1 + std::numeric_limits<float>::epsilon()});
+    // TODO: check that the master volume is really changed
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////// AudioPatches ////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+class AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest {
+protected:
+    bool areAudioPatchesSupported() {
+        auto result = device->supportsAudioPatches();
+        EXPECT_TRUE(result.isOk());
+        return result;
+    }
+};
+
+TEST_F(AudioPatchPrimaryHidlTest, AudioPatches) {
+    doc::test("Test if audio patches are supported");
+    if (!areAudioPatchesSupported()) {
+        doc::partialTest("Audio patches are not supported");
+        return;
+    }
+    // TODO: test audio patches
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 //////////////// Required and recommended audio format support ///////////////
 // From: https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
@@ -310,7 +305,7 @@
 /////////// TODO: move to the beginning of the file for easier update ////////
 //////////////////////////////////////////////////////////////////////////////
 
-class AudioConfigPrimaryTest : public AudioPrimaryHidlTest {
+class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
 public:
     // Cache result ?
     static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
@@ -369,6 +364,20 @@
     }
 };
 
+/** Generate a test name based on an audio config.
+ *
+ * As the only parameter changing are channel mask and sample rate,
+ * only print those ones in the test name.
+ */
+static string generateTestName(const testing::TestParamInfo<AudioConfig>& info) {
+    const AudioConfig& config = info.param;
+    return to_string(info.index) + "__" + to_string(config.sampleRateHz)+ "_" +
+            // "MONO" is more clear than "FRONT_LEFT"
+            ((config.channelMask == AudioChannelMask::OUT_MONO ||
+              config.channelMask == AudioChannelMask::IN_MONO) ?
+                    "MONO" : toString(config.channelMask));
+}
+
 //////////////////////////////////////////////////////////////////////////////
 ///////////////////////////// getInputBufferSize /////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
@@ -406,10 +415,12 @@
 }
 INSTANTIATE_TEST_CASE_P(
         RequiredInputBufferSize, RequiredInputBufferSizeTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()));
+        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
+         &generateTestName);
 INSTANTIATE_TEST_CASE_P(
         SupportedInputBufferSize, RequiredInputBufferSizeTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()));
+        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
+         &generateTestName);
 
 // Test that the recommended capture config are supported or lead to a INVALID_ARGUMENTS return
 class OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
@@ -419,7 +430,8 @@
 }
 INSTANTIATE_TEST_CASE_P(
         RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()));
+        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
+         &generateTestName);
 
 //////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// setScreenState ///////////////////////////////
@@ -453,8 +465,8 @@
 //////////////////////////////// debugDebug //////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-TEST_F(AudioPrimaryHidlTest, debugDump) {
-    doc::test("Check that the hal can dump its state without error");
+template <class DebugDump>
+static void testDebugDump(DebugDump debugDump) {
     FILE* file = tmpfile();
     ASSERT_NE(nullptr, file) << errno;
 
@@ -465,28 +477,23 @@
     hidl_handle handle;
     handle.setTo(nativeHandle, true /*take ownership*/);
 
-    auto ret = device->debugDump(handle);
-    ASSERT_TRUE(ret.isOk());
-
-    // FIXME: debugDump does not return a Result.
+    // TODO: debugDump does not return a Result.
     // This mean that the hal can not report that it not implementing the function.
-    // As the default hal does not implement debugDump, the function can not be tested.
-    /*
-    res = ret;
-    if (res == Result::NOT_SUPPORTED) {
-         doc::partialTest("debugDump is not implemented");
-         return;
-    }
-    ASSERT_OK(res);
-    rewind(file);
+    ASSERT_OK(debugDump(handle));
+
+    rewind(file); // can not fail
 
     // Check that at least one bit was written by the hal
     char buff;
-    ASSERT_EQ(1, fread(&buff, sizeof(buff), 1, file));
-    */
+    ASSERT_EQ(size_t{1}, fread(&buff, sizeof(buff), 1, file));
     EXPECT_EQ(0, fclose(file)) << errno;
 }
 
+TEST_F(AudioPrimaryHidlTest, debugDump) {
+    doc::test("Check that the hal can dump its state without error");
+    testDebugDump([this](const auto& handle){ return device->debugDump(handle); });
+}
+
 //////////////////////////////////////////////////////////////////////////////
 ////////////////////////// open{Output,Input}Stream //////////////////////////
 //////////////////////////////////////////////////////////////////////////////
@@ -526,6 +533,10 @@
         open = true;
     }
 
+    Return<Result> closeStream() {
+        open = false;
+        return stream->close();
+    }
 private:
     void TearDown() override {
         if (open) {
@@ -536,6 +547,7 @@
 protected:
 
     AudioConfig audioConfig;
+    DeviceAddress address = {};
     sp<Stream> stream;
     bool open = false;
 };
@@ -545,12 +557,11 @@
 class OutputStreamTest : public OpenStreamTest<IStreamOut> {
     virtual void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
-
+        address.device = AudioDevice::OUT_DEFAULT;
         const AudioConfig& config = GetParam();
-        DeviceAddress deviceAddr{};  // Ignored by primary hal
         AudioOutputFlag flags = AudioOutputFlag::NONE; // TODO: test all flag combination
         testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
-                 { return device->openOutputStream(handle, deviceAddr, config, flags, cb); },
+                 { return device->openOutputStream(handle, address, config, flags, cb); },
                  config);
     }
 };
@@ -560,14 +571,17 @@
 }
 INSTANTIATE_TEST_CASE_P(
         RequiredOutputStreamConfigSupport, OutputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()));
+        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()),
+         &generateTestName);
 INSTANTIATE_TEST_CASE_P(
         SupportedOutputStreamConfig, OutputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()));
+        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()),
+         &generateTestName);
 
 INSTANTIATE_TEST_CASE_P(
         RecommendedOutputStreamConfigSupport, OutputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()));
+        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()),
+         &generateTestName);
 
 ////////////////////////////// openInputStream //////////////////////////////
 
@@ -575,13 +589,12 @@
 
     virtual void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
-
+        address.device = AudioDevice::IN_DEFAULT;
         const AudioConfig& config = GetParam();
-        DeviceAddress deviceAddr{}; // TODO: test all devices
         AudioInputFlag flags = AudioInputFlag::NONE; // TODO: test all flag combination
         AudioSource source = AudioSource::DEFAULT; // TODO: test all flag combination
         testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
-                 { return device->openInputStream(handle, deviceAddr, config, flags, source, cb); },
+                 { return device->openInputStream(handle, address, config, flags, source, cb); },
                  config);
     }
 };
@@ -592,14 +605,17 @@
 }
 INSTANTIATE_TEST_CASE_P(
         RequiredInputStreamConfigSupport, InputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()));
+        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
+         &generateTestName);
 INSTANTIATE_TEST_CASE_P(
         SupportedInputStreamConfig, InputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()));
+        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
+         &generateTestName);
 
 INSTANTIATE_TEST_CASE_P(
         RecommendedInputStreamConfigSupport, InputStreamTest,
-        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()));
+        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
+         &generateTestName);
 
 //////////////////////////////////////////////////////////////////////////////
 ////////////////////////////// IStream getters ///////////////////////////////
@@ -616,8 +632,40 @@
     return ret;
 }
 
+/* Could not find a way to write a test for two parametrized class fixure
+ * thus use this macro do duplicate tests for Input and Output stream */
+#define TEST_IO_STREAM(test_name, documentation, code) \
+    TEST_P(InputStreamTest, test_name) { \
+        doc::test(documentation); \
+        code; \
+    } \
+    TEST_P(OutputStreamTest, test_name) { \
+        doc::test(documentation); \
+        code; \
+    }
+
+TEST_IO_STREAM(GetFrameCount, "Check that the stream frame count == the one it was opened with",
+               ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
+
+TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
+               ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
+
+TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it was opened with",
+               ASSERT_EQ(audioConfig.channelMask, extract(stream->getChannelMask())))
+
+TEST_IO_STREAM(GetFormat, "Check that the stream format == the one it was opened with",
+               ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
+
+// TODO: for now only check that the framesize is not incoherent
+TEST_IO_STREAM(GetFrameSize, "Check that the stream frame size == the one it was opened with",
+               ASSERT_GT(extract(stream->getFrameSize()), 0U))
+
+TEST_IO_STREAM(GetBufferSize, "Check that the stream buffer size== the one it was opened with",
+               ASSERT_GE(extract(stream->getBufferSize()), \
+                                     extract(stream->getFrameSize())));
+
 template <class Property, class CapabilityGetter, class Getter, class Setter>
-static void testCapabilityGetter(const string& name,IStream* stream, Property currentValue,
+static void testCapabilityGetter(const string& name, IStream* stream, Property currentValue,
                                  CapabilityGetter capablityGetter, Getter getter, Setter setter) {
     hidl_vec<Property> capabilities;
     ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities)));
@@ -640,6 +688,48 @@
     }
 }
 
+TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported",
+               testCapabilityGetter("getSupportedSampleRate", stream.get(), \
+                                    extract(stream->getSampleRate()), \
+                                    &IStream::getSupportedSampleRates, \
+                                    &IStream::getSampleRate, &IStream::setSampleRate))
+
+TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is declared as supported",
+               testCapabilityGetter("getSupportedChannelMask", stream.get(), \
+                                    extract(stream->getChannelMask()), \
+                                    &IStream::getSupportedChannelMasks, \
+                                    &IStream::getChannelMask, &IStream::setChannelMask))
+
+TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported",
+               testCapabilityGetter("getSupportedFormat", stream.get(), \
+                                    extract(stream->getFormat()), \
+                                    &IStream::getSupportedFormats, \
+                                    &IStream::getFormat, &IStream::setFormat))
+
+static void testGetDevice(IStream* stream, AudioDevice expectedDevice) {
+    auto ret = stream->getDevice();
+    ASSERT_TRUE(ret.isOk());
+    AudioDevice device = ret;
+    ASSERT_EQ(expectedDevice, device);
+}
+
+TEST_IO_STREAM(GetDevice, "Check that the stream device == the one it was opened with",
+               areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") : \
+                                            testGetDevice(stream.get(), address.device))
+
+static void testSetDevice(IStream* stream, const DeviceAddress& address) {
+    DeviceAddress otherAddress = address;
+    otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ?
+            AudioDevice::OUT_SPEAKER : AudioDevice::IN_BUILTIN_MIC;
+    EXPECT_OK(stream->setDevice(otherAddress));
+
+    ASSERT_OK(stream->setDevice(address)); // Go back to the original value
+}
+
+TEST_IO_STREAM(SetDevice, "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC",
+               areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") : \
+                                            testSetDevice(stream.get(), address))
+
 static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
     uint32_t sampleRateHz;
     AudioChannelMask mask;
@@ -653,90 +743,191 @@
     EXPECT_EQ(expectedConfig.format, format);
 }
 
-static void testAccessors(IStream* stream, AudioConfig audioConfig) {
-    doc::test("Test IStream getters and setters that can be called in the stop state");
+TEST_IO_STREAM(GetAudioProperties,
+               "Check that the stream audio properties == the ones it was opened with",
+               testGetAudioProperties(stream.get(), audioConfig))
 
-    auto frameCount = extract(stream->getFrameCount());
-    ASSERT_EQ(audioConfig.frameCount, frameCount);
+static void testConnectedState(IStream* stream) {
+    DeviceAddress address = {};
+    using AD = AudioDevice;
+    for (auto device : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
+        address.device = device;
 
-    auto sampleRate = extract(stream->getSampleRate());
-    // FIXME: the qcom hal it does not currently negotiate the sampleRate
-    ASSERT_EQ(audioConfig.sampleRateHz, sampleRate);
-
-    auto channelMask = extract(stream->getChannelMask());
-    // FIXME: the qcom hal it does not currently negotiate the channelMask
-    ASSERT_EQ(audioConfig.channelMask, channelMask);
-
-    auto frameSize = extract(stream->getFrameSize());
-    ASSERT_GE(frameSize, 0U);
-
-    auto bufferSize = extract(stream->getBufferSize());
-    ASSERT_GE(bufferSize, frameSize);
-
-    testCapabilityGetter("getSupportedsampleRate", stream, sampleRate,
-                         &IStream::getSupportedSampleRates,
-                         &IStream::getSampleRate, &IStream::setSampleRate);
-
-    testCapabilityGetter("getSupportedChannelMask", stream, channelMask,
-                         &IStream::getSupportedChannelMasks,
-                         &IStream::getChannelMask, &IStream::setChannelMask);
-
-    AudioFormat format = extract(stream->getFormat());
-    ASSERT_EQ(audioConfig.format, format);
-
-    testCapabilityGetter("getSupportedFormats", stream, format,
-                         &IStream::getSupportedFormats, &IStream::getFormat, &IStream::setFormat);
-
-    testGetAudioProperties(stream, audioConfig);
-
-    auto ret = stream->getDevice();
-    ASSERT_TRUE(ret.isOk());
-    AudioDevice device = ret;
-    ASSERT_EQ(AudioDevice::OUT_DEFAULT, device);
-}
-
-TEST_P(InputStreamTest, GettersTest) {
-    testAccessors(stream.get(), audioConfig);
-}
-TEST_P(OutputStreamTest, GettersTest) {
-    testAccessors(stream.get(), audioConfig);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////// AudioPatches ////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-
-TEST_F(AudioPrimaryHidlTest, AudioPatches) {
-    doc::test("Test if audio patches are supported");
-    auto result = device->supportsAudioPatches();
-    ASSERT_TRUE(result.isOk());
-    bool supportsAudioPatch = result;
-    if (!supportsAudioPatch) {
-        doc::partialTest("Audio patches are not supported");
-        return;
+        ASSERT_OK(stream->setConnectedState(address, true));
+        ASSERT_OK(stream->setConnectedState(address, false));
     }
-    // TODO: test audio patches
+}
+TEST_IO_STREAM(SetConnectedState,
+               "Check that the stream can be notified of device connection and deconnection",
+               testConnectedState(stream.get()))
+
+
+static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
+TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
+               ASSERT_RESULT(invalidArgsOrNotSupported, stream->setHwAvSync(666)))
+
+static void checkGetParameter(IStream* stream, hidl_vec<hidl_string> keys,
+                              vector<Result> expectedResults) {
+    hidl_vec<ParameterValue> parameters;
+    Result res;
+    ASSERT_OK(stream->getParameters(keys, returnIn(res, parameters)));
+    ASSERT_RESULT(expectedResults, res);
+    if (res == Result::OK) {
+        ASSERT_EQ(0U, parameters.size());
+    }
+}
+
+/* Get/Set parameter is intended to be an opaque channel between vendors app and their HALs.
+ * Thus can not be meaningfully tested.
+ * TODO: Doc missing. Should asking for an empty set of params raise an error ?
+ */
+TEST_IO_STREAM(getEmptySetParameter, "Retrieve the values of an empty set",
+               checkGetParameter(stream.get(), {} /* keys */,
+                                 {Result::OK, Result::INVALID_ARGUMENTS}))
+
+
+TEST_IO_STREAM(getNonExistingParameter, "Retrieve the values of an non existing parameter",
+               checkGetParameter(stream.get(), {"Non existing key"} /* keys */,
+                                 {Result::INVALID_ARGUMENTS}))
+
+static vector<Result> okOrNotSupported = {Result::OK, Result::INVALID_ARGUMENTS};
+TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
+               ASSERT_RESULT(okOrNotSupported, stream->setParameters({})))
+
+TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
+               ASSERT_RESULT(Result::INVALID_ARGUMENTS,
+                             stream->setParameters({{"non existing key", "0"}})))
+
+TEST_IO_STREAM(DebugDump,
+               "Check that a stream can dump its state without error",
+               testDebugDump([this](const auto& handle){ return stream->debugDump(handle); }))
+
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////// addRemoveEffect ///////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+TEST_IO_STREAM(AddNonExistingEffect, "Adding a non existing effect should fail",
+               ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->addEffect(666)))
+TEST_IO_STREAM(RemoveNonExistingEffect, "Removing a non existing effect should fail",
+               ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->removeEffect(666)))
+
+//TODO: positive tests
+
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// Control ////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+TEST_IO_STREAM(standby, "Make sure the stream can be put in stanby",
+               ASSERT_OK(stream->standby())) // can not fail
+
+static vector<Result> invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
+
+TEST_IO_STREAM(startNoMmap, "Starting a mmaped stream before mapping it should fail",
+               ASSERT_RESULT(invalidStateOrNotSupported, stream->start()))
+
+TEST_IO_STREAM(stopNoMmap, "Stopping a mmaped stream before mapping it should fail",
+               ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
+
+TEST_IO_STREAM(getMmapPositionNoMmap, "Get a stream Mmap position before mapping it should fail",
+               ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
+
+TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
+TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
+               ASSERT_OK(closeStream()); \
+               ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
+
+static void testCreateTooBigMmapBuffer(IStream* stream) {
+    MmapBufferInfo info;
+    Result res;
+    // Assume that int max is a value too big to be allocated
+    // This is true currently with a 32bit media server, but might not when it will run in 64 bit
+    auto minSizeFrames = std::numeric_limits<int32_t>::max();
+    ASSERT_OK(stream->createMmapBuffer(minSizeFrames, returnIn(res, info)));
+    ASSERT_RESULT(invalidArgsOrNotSupported, res);
+}
+
+TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer too big should fail",
+               testCreateTooBigMmapBuffer(stream.get()))
+
+
+static void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
+    Result res;
+    MmapPosition position;
+    ASSERT_OK(stream->getMmapPosition(returnIn(res, position)));
+    ASSERT_RESULT(invalidArgsOrNotSupported, res);
+}
+
+TEST_IO_STREAM(GetMmapPositionOfNonMmapedStream,
+               "Retrieving the mmap position of a non mmaped stream should fail",
+               testGetMmapPositionOfNonMmapedStream(stream.get()))
+
+//////////////////////////////////////////////////////////////////////////////
+///////////////////////////////// StreamIn ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+TEST_P(InputStreamTest, GetAudioSource) {
+    doc::test("Retrieving the audio source of an input stream should always succeed");
+    AudioSource source;
+    ASSERT_OK(stream->getAudioSource(returnIn(res, source)));
+    ASSERT_OK(res);
+    ASSERT_EQ(AudioSource::DEFAULT, source);
+}
+
+static void testUnitaryGain(std::function<Return<Result> (float)> setGain) {
+    for (float value : {0.0, 0.01, 0.5, 0.09, 1.0}) {
+        SCOPED_TRACE("value=" + to_string(value));
+        ASSERT_OK(setGain(value));
+    }
+    for (float value : (float[]){-INFINITY,-1.0, -0.0,
+                                 1.0 + std::numeric_limits<float>::epsilon(), 2.0, INFINITY,
+                                 NAN}) {
+        SCOPED_TRACE("value=" + to_string(value));
+        // FIXME: NAN should never be accepted
+        // FIXME: Missing api doc. What should the impl do if the volume is outside [0,1] ?
+        ASSERT_RESULT(Result::INVALID_ARGUMENTS, setGain(value));
+    }
+}
+
+TEST_P(InputStreamTest, SetGain) {
+    doc::test("The gain of an input stream should only be set between [0,1]");
+    testUnitaryGain([this](float volume) { return stream->setGain(volume); });
+}
+
+static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_t framesCount) {
+    Result res;
+    // Ignore output parameters as the call should fail
+    ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
+                                        [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
+    EXPECT_RESULT(invalidArgsOrNotSupported, res);
+}
+
+TEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) {
+    doc::test("Preparing a stream for reading with a 2^32 sized buffer should fail");
+    testPrepareForReading(stream.get(), 1, std::numeric_limits<uint32_t>::max());
+}
+
+TEST_P(InputStreamTest, PrepareForReadingCheckOverflow) {
+    doc::test("Preparing a stream for reading with a overflowing sized buffer should fail");
+    auto uintMax = std::numeric_limits<uint32_t>::max();
+    testPrepareForReading(stream.get(), uintMax, uintMax);
+}
+
+TEST_P(InputStreamTest, getCapturePosition) {
+    doc::test("The capture position of a non prepared stream should not be retrievable");
+    uint64_t frames;
+    uint64_t time;
+    ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
+    ASSERT_RESULT(invalidStateOrNotSupported, res);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// PrimaryDevice ////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
+
 TEST_F(AudioPrimaryHidlTest, setVoiceVolume) {
     doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
-    for (float volume : {0.0, 0.01, 0.5, 0.09, 1.0}) {
-        SCOPED_TRACE("volume=" + to_string(volume));
-        ASSERT_OK(device->setVoiceVolume(volume));
-    }
-    for (float volume : (float[]){-INFINITY,-1.0, -0.0,
-                                  1.0 + std::numeric_limits<float>::epsilon(), 2.0, INFINITY,
-                                  NAN}) {
-        SCOPED_TRACE("volume=" + to_string(volume));
-        // FIXME: NAN should never be accepted
-        // FIXME: Missing api doc. What should the impl do if the volume is outside [0,1] ?
-        ASSERT_INVALID_ARGUMENTS(device->setVoiceVolume(volume));
-    }
+    testUnitaryGain([this](float volume) { return device->setVoiceVolume(volume); });
 }
 
 TEST_F(AudioPrimaryHidlTest, setMode) {
@@ -749,7 +940,7 @@
     }
 
     // FIXME: Missing api doc. What should the impl do if the mode is invalid ?
-    ASSERT_INVALID_ARGUMENTS(device->setMode(AudioMode::INVALID));
+    ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(AudioMode::INVALID));
 }
 
 
diff --git a/audio/2.0/vts/functional/utility/AssertOk.h b/audio/2.0/vts/functional/utility/AssertOk.h
index 16488ae..39c9a1d 100644
--- a/audio/2.0/vts/functional/utility/AssertOk.h
+++ b/audio/2.0/vts/functional/utility/AssertOk.h
@@ -13,38 +13,59 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+#include <vector>
+#include <algorithm>
+
 #include <hidl/Status.h>
 
 namespace detail {
 
-inline void assertOk(::android::hardware::Return<void> ret) {
+// This is a detail namespace, thus it is OK to import a class as nobody else is allowed to use it
+using ::android::hardware::Return;
+using ::android::hardware::audio::V2_0::Result;
+
+inline void assertResult(Result expected, Result result) {
+    ASSERT_EQ(expected, result);
+}
+
+inline void assertResult(Result expected, Return<Result> ret) {
+    ASSERT_TRUE(ret.isOk());
+    Result result = ret;
+    assertResult(expected, result);
+}
+
+inline void assertResult(std::vector<Result> expected, Result result) {
+    if (std::find(expected.begin(), expected.end(), result) != expected.end()) {
+        return; // result is in expected
+    }
+    FAIL() << "Expected result " << ::testing::PrintToString(result)
+           << " to be one of " << ::testing::PrintToString(expected);
+}
+
+inline void assertResult(std::vector<Result> expected, Return<Result> ret) {
+    ASSERT_TRUE(ret.isOk());
+    Result result = ret;
+    assertResult(expected, result);
+}
+
+inline void assertOk(Return<void> ret) {
     ASSERT_TRUE(ret.isOk());
 }
 
-inline void assertOk(::android::hardware::audio::V2_0::Result result) {
-    ASSERT_EQ(decltype(result)::OK, result);
+inline void assertOk(Result result) {
+    assertResult(Result::OK, result);
 }
 
-inline void assertOk(::android::hardware::Return<::android::hardware::audio::V2_0::Result> ret) {
-    ASSERT_TRUE(ret.isOk());
-    ::android::hardware::audio::V2_0::Result result = ret;
-    assertOk(result);
+inline void assertOk(Return<Result> ret) {
+    assertResult(Result::OK, std::move(ret));
 }
 
-inline void assertInvalidArguments(::android::hardware::audio::V2_0::Result result) {
-    ASSERT_EQ(decltype(result)::INVALID_ARGUMENTS, result);
-}
-
-inline void assertInvalidArguments(
-        ::android::hardware::Return<::android::hardware::audio::V2_0::Result> ret) {
-    ASSERT_TRUE(ret.isOk());
-    ::android::hardware::audio::V2_0::Result result = ret;
-    assertInvalidArguments(result);
-}
 }
 
 // Test anything provided is and contains only OK
 #define ASSERT_OK(ret) ASSERT_NO_FATAL_FAILURE(detail::assertOk(ret))
 #define EXPECT_OK(ret) EXPECT_NO_FATAL_FAILURE(detail::assertOk(ret))
 
-#define ASSERT_INVALID_ARGUMENTS(ret) ASSERT_NO_FATAL_FAILURE(detail::assertInvalidArguments(ret))
+#define ASSERT_RESULT(expected, ret) ASSERT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
+#define EXPECT_RESULT(expected, ret) ASSERT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
diff --git a/audio/2.0/vts/functional/utility/PrettyPrintAudioTypes.h b/audio/2.0/vts/functional/utility/PrettyPrintAudioTypes.h
index 8dfcb29..025cd1c 100644
--- a/audio/2.0/vts/functional/utility/PrettyPrintAudioTypes.h
+++ b/audio/2.0/vts/functional/utility/PrettyPrintAudioTypes.h
@@ -13,23 +13,50 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <type_traits>
 
-// Use HIDL generated toString methods to pretty print gtest errors
+/** @file Use HIDL generated toString methods to pretty print gtest errors */
+
+namespace detail {
+
+// Print the value of an enum as hex
+template <class Enum>
+inline void printUnderlyingValue(Enum value, ::std::ostream* os) {
+    *os << std::hex << " (0x" << static_cast<std::underlying_type_t<Enum>>(value) << ")";
+}
+
+} // namespace detail
+
 namespace android {
 namespace hardware {
 namespace audio {
 namespace V2_0 {
+
 inline void PrintTo(const Result& result, ::std::ostream* os) {
     *os << toString(result);
+    detail::printUnderlyingValue(result, os);
 }
+
 } // namespace V2_0
 namespace common {
 namespace V2_0 {
+
 inline void PrintTo(const AudioConfig& config, ::std::ostream* os) {
     *os << toString(config);
 }
+
+inline void PrintTo(const AudioDevice& device, ::std::ostream* os) {
+    *os << toString(device);
+    detail::printUnderlyingValue(device, os);
+}
+
+inline void PrintTo(const AudioChannelMask& channelMask, ::std::ostream* os) {
+    *os << toString(channelMask);
+    detail::printUnderlyingValue(channelMask, os);
+}
+
 } // namespace V2_0
 } // namespace common
-}
-}
-}
+} // namespace audio
+} // namespace hardware
+} // namespace android
diff --git a/audio/effect/2.0/IEffect.hal b/audio/effect/2.0/IEffect.hal
index 9e10117..d254e8c 100644
--- a/audio/effect/2.0/IEffect.hal
+++ b/audio/effect/2.0/IEffect.hal
@@ -59,7 +59,7 @@
      *
      * @return retval operation completion status.
      */
-    @callflow(next={"process"})
+    @callflow(next={"prepareForProcessing"})
     enable() generates (Result retval);
 
     /*
@@ -67,7 +67,7 @@
      *
      * @return retval operation completion status.
      */
-    @exit
+    @callflow(next={"close"})
     disable() generates (Result retval);
 
     /*
@@ -75,6 +75,9 @@
      * effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its
      * descriptor to receive this command when the device changes.
      *
+     * Note: this method is only supported for effects inserted into
+     *       the output chain.
+     *
      * @param device output device specification.
      * @return retval operation completion status.
      */
@@ -145,6 +148,9 @@
      * implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to
      * receive this command when the device changes.
      *
+     * Note: this method is only supported for effects inserted into
+     *       the input chain.
+     *
      * @param device input device specification.
      * @return retval operation completion status.
      */
@@ -209,6 +215,9 @@
      * Set the audio source the capture path is configured for (Camcorder, voice
      * recognition...).
      *
+     * Note: this method is only supported for effects inserted into
+     *       the input chain.
+     *
      * @param source source descriptor.
      * @return retval operation completion status.
      */
@@ -258,6 +267,7 @@
      *                                  the queue.
      * @return statusMQ a message queue used for passing status from the effect.
      */
+    @callflow(next={"setProcessBuffers"})
     prepareForProcessing() generates (Result retval, fmq_sync<Result> statusMQ);
 
     /*
@@ -275,6 +285,7 @@
      *                INVALID_ARGUMENTS if there was a problem with mapping
      *                                  any of the buffers.
      */
+    @callflow(next={"*"})
     setProcessBuffers(AudioBuffer inBuffer, AudioBuffer outBuffer) generates (
             Result retval);
 
@@ -423,5 +434,6 @@
      * @return retval OK in case the success.
      *                INVALID_STATE if the effect was already closed.
      */
+    @exit
     close() generates (Result retval);
 };
diff --git a/audio/effect/2.0/IEqualizerEffect.hal b/audio/effect/2.0/IEqualizerEffect.hal
index afcc4b6..b8fa177 100644
--- a/audio/effect/2.0/IEqualizerEffect.hal
+++ b/audio/effect/2.0/IEqualizerEffect.hal
@@ -29,34 +29,36 @@
      * Returns the minimum and maximum band levels supported.
      */
     getLevelRange()
-            generates (Result retval, uint16_t minLevel, uint16_t maxLevel);
+            generates (Result retval, int16_t minLevel, int16_t maxLevel);
 
     /*
      * Sets the gain for the given equalizer band.
      */
-    setBandLevel(uint16_t band, uint16_t level) generates (Result retval);
+    setBandLevel(uint16_t band, int16_t level) generates (Result retval);
 
     /*
      * Gets the gain for the given equalizer band.
      */
-    getBandLevel(uint16_t band) generates (Result retval, uint16_t level);
+    getBandLevel(uint16_t band) generates (Result retval, int16_t level);
 
     /*
-     * Gets the center frequency of the given band.
+     * Gets the center frequency of the given band, in milliHertz.
      */
     getBandCenterFrequency(uint16_t band)
-            generates (Result retval, uint32_t centerFreq);
+            generates (Result retval, uint32_t centerFreqmHz);
 
     /*
-     * Gets the frequency range of the given frequency band.
+     * Gets the frequency range of the given frequency band, in milliHertz.
      */
     getBandFrequencyRange(uint16_t band)
-            generates (Result retval, uint32_t minFreqHz, uint32_t maxFreqHz);
+            generates (Result retval, uint32_t minFreqmHz, uint32_t maxFreqmHz);
 
     /*
-     * Gets the band that has the most effect on the given frequency.
+     * Gets the band that has the most effect on the given frequency
+     * in milliHertz.
      */
-    getBandForFrequency(uint32_t freq) generates (Result retval, uint16_t band);
+    getBandForFrequency(uint32_t freqmHz)
+            generates (Result retval, uint16_t band);
 
     /*
      * Gets the names of all presets the equalizer supports.
@@ -76,7 +78,7 @@
 
     struct AllProperties {
         uint16_t curPreset;
-        vec<uint16_t> bandLevels;
+        vec<int16_t> bandLevels;
     };
 
     /*
diff --git a/audio/effect/2.0/default/Effect.cpp b/audio/effect/2.0/default/Effect.cpp
index 83c8e09..6704239 100644
--- a/audio/effect/2.0/default/Effect.cpp
+++ b/audio/effect/2.0/default/Effect.cpp
@@ -188,6 +188,8 @@
 // static
 void Effect::effectBufferConfigFromHal(
         const buffer_config_t& halConfig, EffectBufferConfig* config) {
+    config->buffer.id = 0;
+    config->buffer.frameCount = 0;
     config->samplingRateHz = halConfig.samplingRate;
     config->channels = AudioChannelMask(halConfig.channels);
     config->format = AudioFormat(halConfig.format);
@@ -282,7 +284,7 @@
 
 void Effect::getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb) {
     uint32_t halResultSize = sizeof(effect_config_t);
-    effect_config_t halConfig;
+    effect_config_t halConfig{};
     status_t status = (*mHandle)->command(
             mHandle, commandCode, 0, NULL, &halResultSize, &halConfig);
     EffectConfig config;
@@ -309,15 +311,16 @@
 Result Effect::getParameterImpl(
         uint32_t paramSize,
         const void* paramData,
-        uint32_t valueSize,
+        uint32_t requestValueSize,
+        uint32_t replyValueSize,
         GetParameterSuccessCallback onSuccess) {
     // As it is unknown what method HAL uses for copying the provided parameter data,
     // it is safer to make sure that input and output buffers do not overlap.
     std::vector<uint8_t> halCmdBuffer =
-            parameterToHal(paramSize, paramData, valueSize, nullptr);
+            parameterToHal(paramSize, paramData, requestValueSize, nullptr);
     const void *valueData = nullptr;
     std::vector<uint8_t> halParamBuffer =
-            parameterToHal(paramSize, paramData, valueSize, &valueData);
+            parameterToHal(paramSize, paramData, replyValueSize, &valueData);
     uint32_t halParamBufferSize = halParamBuffer.size();
 
     return sendCommandReturningStatusAndData(
diff --git a/audio/effect/2.0/default/Effect.h b/audio/effect/2.0/default/Effect.h
index 13faec4..0918cd8 100644
--- a/audio/effect/2.0/default/Effect.h
+++ b/audio/effect/2.0/default/Effect.h
@@ -60,6 +60,8 @@
 
 struct Effect : public IEffect {
     typedef MessageQueue<Result, kSynchronizedReadWrite> StatusMQ;
+    using GetParameterSuccessCallback =
+            std::function<void(uint32_t valueSize, const void* valueData)>;
 
     explicit Effect(effect_handle_t handle);
 
@@ -163,6 +165,22 @@
         return setParameterImpl(sizeof(params), params, sizeof(T), &paramValue);
     }
 
+    Result getParameterImpl(
+            uint32_t paramSize,
+            const void* paramData,
+            uint32_t valueSize,
+            GetParameterSuccessCallback onSuccess) {
+        return getParameterImpl(paramSize, paramData, valueSize, valueSize, onSuccess);
+    }
+    Result getParameterImpl(
+            uint32_t paramSize,
+            const void* paramData,
+            uint32_t requestValueSize,
+            uint32_t replyValueSize,
+            GetParameterSuccessCallback onSuccess);
+    Result setParameterImpl(
+            uint32_t paramSize, const void* paramData, uint32_t valueSize, const void* valueData);
+
   private:
     friend struct VirtualizerEffect;  // for getParameterImpl
     friend struct VisualizerEffect;   // to allow executing commands
@@ -170,8 +188,6 @@
     using CommandSuccessCallback = std::function<void()>;
     using GetConfigCallback = std::function<void(Result retval, const EffectConfig& config)>;
     using GetCurrentConfigSuccessCallback = std::function<void(void* configData)>;
-    using GetParameterSuccessCallback =
-            std::function<void(uint32_t valueSize, const void* valueData)>;
     using GetSupportedConfigsSuccessCallback =
             std::function<void(uint32_t supportedConfigs, void* configsData)>;
 
@@ -220,11 +236,6 @@
     void getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb);
     Result getCurrentConfigImpl(
             uint32_t featureId, uint32_t configSize, GetCurrentConfigSuccessCallback onSuccess);
-    Result getParameterImpl(
-            uint32_t paramSize,
-            const void* paramData,
-            uint32_t valueSize,
-            GetParameterSuccessCallback onSuccess);
     Result getSupportedConfigsImpl(
             uint32_t featureId,
             uint32_t maxConfigs,
@@ -252,8 +263,6 @@
             const EffectConfig& config,
             const sp<IEffectBufferProviderCallback>& inputBufferProvider,
             const sp<IEffectBufferProviderCallback>& outputBufferProvider);
-    Result setParameterImpl(
-            uint32_t paramSize, const void* paramData, uint32_t valueSize, const void* valueData);
 };
 
 }  // namespace implementation
diff --git a/audio/effect/2.0/default/EffectsFactory.cpp b/audio/effect/2.0/default/EffectsFactory.cpp
index 572a428..08d92bd 100644
--- a/audio/effect/2.0/default/EffectsFactory.cpp
+++ b/audio/effect/2.0/default/EffectsFactory.cpp
@@ -95,7 +95,7 @@
     status = EffectQueryNumberEffects(&numEffects);
     if (status != OK) {
         retval = Result::NOT_INITIALIZED;
-        ALOGW("Error querying number of effects: %s", strerror(-status));
+        ALOGE("Error querying number of effects: %s", strerror(-status));
         goto exit;
     }
     result.resize(numEffects);
@@ -105,7 +105,7 @@
         if (status == OK) {
             effectDescriptorFromHal(halDescriptor, &result[i]);
         } else {
-            ALOGW("Error querying effect at position %d / %d: %s",
+            ALOGE("Error querying effect at position %d / %d: %s",
                     i, numEffects, strerror(-status));
             switch (status) {
                 case -ENOSYS: {
@@ -139,7 +139,7 @@
     effectDescriptorFromHal(halDescriptor, &descriptor);
     Result retval(Result::OK);
     if (status != OK) {
-        ALOGW("Error querying effect descriptor for %s: %s",
+        ALOGE("Error querying effect descriptor for %s: %s",
                 uuidToString(halUuid).c_str(), strerror(-status));
         if (status == -ENOENT) {
             retval = Result::INVALID_ARGUMENTS;
@@ -168,11 +168,13 @@
             effect = dispatchEffectInstanceCreation(halDescriptor, handle);
             effectId = EffectMap::getInstance().add(handle);
         } else {
+            ALOGE("Error querying effect descriptor for %s: %s",
+                    uuidToString(halUuid).c_str(), strerror(-status));
             EffectRelease(handle);
         }
     }
     if (status != OK) {
-        ALOGW("Error creating effect %s: %s", uuidToString(halUuid).c_str(), strerror(-status));
+        ALOGE("Error creating effect %s: %s", uuidToString(halUuid).c_str(), strerror(-status));
         if (status == -ENOENT) {
             retval = Result::INVALID_ARGUMENTS;
         } else {
diff --git a/audio/effect/2.0/default/EqualizerEffect.cpp b/audio/effect/2.0/default/EqualizerEffect.cpp
index 223716c..808d8eb 100644
--- a/audio/effect/2.0/default/EqualizerEffect.cpp
+++ b/audio/effect/2.0/default/EqualizerEffect.cpp
@@ -35,10 +35,15 @@
 EqualizerEffect::~EqualizerEffect() {}
 
 void EqualizerEffect::propertiesFromHal(
-        t_equalizer_settings& halProperties,
+        const t_equalizer_settings& halProperties,
         IEqualizerEffect::AllProperties* properties) {
     properties->curPreset = halProperties.curPreset;
-    properties->bandLevels.setToExternal(&halProperties.bandLevels[0], halProperties.numBands);
+    // t_equalizer_settings incorrectly defines bandLevels as uint16_t,
+    // whereas the actual type of values used by effects is int16_t.
+    const int16_t* signedBandLevels =
+            reinterpret_cast<const int16_t*>(&halProperties.bandLevels[0]);
+    properties->bandLevels.setToExternal(
+            const_cast<int16_t*>(signedBandLevels), halProperties.numBands);
 }
 
 std::vector<uint8_t> EqualizerEffect::propertiesToHal(
@@ -200,18 +205,18 @@
 }
 
 Return<void> EqualizerEffect::getLevelRange(getLevelRange_cb _hidl_cb)  {
-    uint16_t halLevels[2] = { 0, 0 };
+    int16_t halLevels[2] = { 0, 0 };
     Result retval = mEffect->getParam(EQ_PARAM_LEVEL_RANGE, halLevels);
     _hidl_cb(retval, halLevels[0], halLevels[1]);
     return Void();
 }
 
-Return<Result> EqualizerEffect::setBandLevel(uint16_t band, uint16_t level)  {
+Return<Result> EqualizerEffect::setBandLevel(uint16_t band, int16_t level)  {
     return mEffect->setParam(EQ_PARAM_BAND_LEVEL, band, level);
 }
 
 Return<void> EqualizerEffect::getBandLevel(uint16_t band, getBandLevel_cb _hidl_cb)  {
-    uint16_t halLevel = 0;
+    int16_t halLevel = 0;
     Result retval = mEffect->getParam(EQ_PARAM_BAND_LEVEL, band, halLevel);
     _hidl_cb(retval, halLevel);
     return Void();
@@ -272,14 +277,28 @@
         const IEqualizerEffect::AllProperties& properties)  {
     t_equalizer_settings *halPropertiesPtr = nullptr;
     std::vector<uint8_t> halBuffer = propertiesToHal(properties, &halPropertiesPtr);
-    return mEffect->setParam(EQ_PARAM_PROPERTIES, *halPropertiesPtr);
+    uint32_t paramId = EQ_PARAM_PROPERTIES;
+    return mEffect->setParameterImpl(
+            sizeof(paramId), &paramId, halBuffer.size(), halPropertiesPtr);
 }
 
 Return<void> EqualizerEffect::getAllProperties(getAllProperties_cb _hidl_cb)  {
-    t_equalizer_settings halProperties;
-    Result retval = mEffect->getParam(EQ_PARAM_PROPERTIES, halProperties);
+    uint16_t numBands = 0;
+    Result retval = mEffect->getParam(EQ_PARAM_NUM_BANDS, numBands);
     AllProperties properties;
-    propertiesFromHal(halProperties, &properties);
+    if (retval != Result::OK) {
+        _hidl_cb(retval, properties);
+        return Void();
+    }
+    size_t valueSize = sizeof(t_equalizer_settings) + sizeof(int16_t) * numBands;
+    uint32_t paramId = EQ_PARAM_PROPERTIES;
+    retval = mEffect->getParameterImpl(
+            sizeof(paramId), &paramId, valueSize,
+            [&] (uint32_t, const void* valueData) {
+                const t_equalizer_settings* halProperties =
+                        reinterpret_cast<const t_equalizer_settings*>(valueData);
+                propertiesFromHal(*halProperties, &properties);
+            });
     _hidl_cb(retval, properties);
     return Void();
 }
diff --git a/audio/effect/2.0/default/EqualizerEffect.h b/audio/effect/2.0/default/EqualizerEffect.h
index c9bed4f..9e8d75b 100644
--- a/audio/effect/2.0/default/EqualizerEffect.h
+++ b/audio/effect/2.0/default/EqualizerEffect.h
@@ -114,7 +114,7 @@
     // Methods from ::android::hardware::audio::effect::V2_0::IEqualizerEffect follow.
     Return<void> getNumBands(getNumBands_cb _hidl_cb)  override;
     Return<void> getLevelRange(getLevelRange_cb _hidl_cb)  override;
-    Return<Result> setBandLevel(uint16_t band, uint16_t level)  override;
+    Return<Result> setBandLevel(uint16_t band, int16_t level)  override;
     Return<void> getBandLevel(uint16_t band, getBandLevel_cb _hidl_cb)  override;
     Return<void> getBandCenterFrequency(
             uint16_t band, getBandCenterFrequency_cb _hidl_cb)  override;
@@ -132,7 +132,7 @@
     virtual ~EqualizerEffect();
 
     void propertiesFromHal(
-            t_equalizer_settings& halProperties,
+            const t_equalizer_settings& halProperties,
             IEqualizerEffect::AllProperties* properties);
     std::vector<uint8_t> propertiesToHal(
             const IEqualizerEffect::AllProperties& properties,
diff --git a/audio/effect/2.0/default/LoudnessEnhancerEffect.cpp b/audio/effect/2.0/default/LoudnessEnhancerEffect.cpp
index e58b42c..fda5eb0 100644
--- a/audio/effect/2.0/default/LoudnessEnhancerEffect.cpp
+++ b/audio/effect/2.0/default/LoudnessEnhancerEffect.cpp
@@ -182,7 +182,18 @@
 }
 
 Return<void> LoudnessEnhancerEffect::getTargetGain(getTargetGain_cb _hidl_cb)  {
-    return mEffect->getIntegerParam(LOUDNESS_ENHANCER_DEFAULT_TARGET_GAIN_MB, _hidl_cb);
+    // AOSP Loudness Enhancer expects the size of the request to not include the
+    // size of the parameter.
+    uint32_t paramId = LOUDNESS_ENHANCER_DEFAULT_TARGET_GAIN_MB;
+    uint32_t targetGainMb = 0;
+    Result retval = mEffect->getParameterImpl(
+            sizeof(paramId), &paramId,
+            0, sizeof(targetGainMb),
+            [&] (uint32_t, const void* valueData) {
+                memcpy(&targetGainMb, valueData, sizeof(targetGainMb));
+            });
+    _hidl_cb(retval, targetGainMb);
+    return Void();
 }
 
 } // namespace implementation
diff --git a/audio/effect/2.0/vts/functional/Android.bp b/audio/effect/2.0/vts/functional/Android.bp
index 1bc3f39..8a370cd 100644
--- a/audio/effect/2.0/vts/functional/Android.bp
+++ b/audio/effect/2.0/vts/functional/Android.bp
@@ -26,7 +26,10 @@
         "libhidltransport",
         "libnativehelper",
         "libutils",
+        "android.hardware.audio.common@2.0",
         "android.hardware.audio.effect@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
     ],
     static_libs: ["VtsHalHidlTargetTestBase"],
     cflags: [
diff --git a/audio/effect/2.0/vts/functional/VtsHalAudioEffectV2_0TargetTest.cpp b/audio/effect/2.0/vts/functional/VtsHalAudioEffectV2_0TargetTest.cpp
index 063243b..f6da213 100644
--- a/audio/effect/2.0/vts/functional/VtsHalAudioEffectV2_0TargetTest.cpp
+++ b/audio/effect/2.0/vts/functional/VtsHalAudioEffectV2_0TargetTest.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -16,47 +16,67 @@
 
 #define LOG_TAG "AudioEffectHidlHalTest"
 #include <android-base/logging.h>
-#include <cutils/native_handle.h>
+#include <system/audio.h>
 
+#include <android/hardware/audio/effect/2.0/IEffect.h>
 #include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
+#include <android/hardware/audio/effect/2.0/IEqualizerEffect.h>
+#include <android/hardware/audio/effect/2.0/ILoudnessEnhancerEffect.h>
 #include <android/hardware/audio/effect/2.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
 
 #include <VtsHalHidlTargetTestBase.h>
 
-using ::android::hardware::audio::common::V2_0::Uuid;
-using ::android::hardware::audio::effect::V2_0::EffectDescriptor;
-using ::android::hardware::audio::effect::V2_0::IEffect;
-using ::android::hardware::audio::effect::V2_0::IEffectsFactory;
-using ::android::hardware::audio::effect::V2_0::Result;
-using ::android::hardware::Return;
-using ::android::hardware::Status;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::sp;
+using android::hardware::audio::common::V2_0::AudioDevice;
+using android::hardware::audio::common::V2_0::AudioHandleConsts;
+using android::hardware::audio::common::V2_0::AudioMode;
+using android::hardware::audio::common::V2_0::Uuid;
+using android::hardware::audio::effect::V2_0::AudioBuffer;
+using android::hardware::audio::effect::V2_0::EffectBufferConfig;
+using android::hardware::audio::effect::V2_0::EffectConfig;
+using android::hardware::audio::effect::V2_0::EffectDescriptor;
+using android::hardware::audio::effect::V2_0::EffectOffloadParameter;
+using android::hardware::audio::effect::V2_0::IEffect;
+using android::hardware::audio::effect::V2_0::IEffectsFactory;
+using android::hardware::audio::effect::V2_0::IEqualizerEffect;
+using android::hardware::audio::effect::V2_0::ILoudnessEnhancerEffect;
+using android::hardware::audio::effect::V2_0::Result;
+using android::hardware::MQDescriptorSync;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::hidl_memory;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hidl::allocator::V1_0::IAllocator;
+using android::hidl::memory::V1_0::IMemory;
+using android::sp;
 
-// The main test class for Audio Effect HIDL HAL.
-class AudioEffectHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+#endif
+
+// The main test class for Audio Effects Factory HIDL HAL.
+class AudioEffectsFactoryHidlTest : public ::testing::VtsHalHidlTargetTestBase {
  public:
-  virtual void SetUp() override {
-    effectsFactory = ::testing::VtsHalHidlTargetTestBase::getService<IEffectsFactory>();
+  void SetUp() override {
+    effectsFactory =
+        ::testing::VtsHalHidlTargetTestBase::getService<IEffectsFactory>();
     ASSERT_NE(effectsFactory, nullptr);
   }
 
-  virtual void TearDown() override {}
+  void TearDown() override { effectsFactory.clear(); }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
 
   sp<IEffectsFactory> effectsFactory;
 };
 
-// A class for test environment setup (kept since this file is a template).
-class AudioEffectHidlEnvironment : public ::testing::Environment {
- public:
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-
- private:
-};
-
-TEST_F(AudioEffectHidlTest, EnumerateEffects) {
+TEST_F(AudioEffectsFactoryHidlTest, EnumerateEffects) {
+  description("Verify that EnumerateEffects returns at least one effect");
   Result retval = Result::NOT_INITIALIZED;
   size_t effectCount = 0;
   Return<void> ret = effectsFactory->getAllDescriptors(
@@ -65,11 +85,12 @@
         effectCount = result.size();
       });
   EXPECT_TRUE(ret.isOk());
-  EXPECT_EQ(retval, Result::OK);
+  EXPECT_EQ(Result::OK, retval);
   EXPECT_GT(effectCount, 0u);
 }
 
-TEST_F(AudioEffectHidlTest, CreateEffect) {
+TEST_F(AudioEffectsFactoryHidlTest, CreateEffect) {
+  description("Verify that an effect can be created via CreateEffect");
   bool gotEffect = false;
   Uuid effectUuid;
   Return<void> ret = effectsFactory->getAllDescriptors(
@@ -84,7 +105,7 @@
   Result retval = Result::NOT_INITIALIZED;
   sp<IEffect> effect;
   ret = effectsFactory->createEffect(
-      effectUuid, 1 /* session */, 1 /* ioHandle */,
+      effectUuid, 1 /*session*/, 1 /*ioHandle*/,
       [&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
         retval = r;
         if (r == Result::OK) {
@@ -92,11 +113,14 @@
         }
       });
   EXPECT_TRUE(ret.isOk());
-  EXPECT_EQ(retval, Result::OK);
-  EXPECT_NE(effect, nullptr);
+  EXPECT_EQ(Result::OK, retval);
+  EXPECT_NE(nullptr, effect.get());
 }
 
-TEST_F(AudioEffectHidlTest, GetDescriptor) {
+TEST_F(AudioEffectsFactoryHidlTest, GetDescriptor) {
+  description(
+      "Verify that effects factory can provide an effect descriptor via "
+      "GetDescriptor");
   hidl_vec<EffectDescriptor> allDescriptors;
   Return<void> ret = effectsFactory->getAllDescriptors(
       [&](Result r, const hidl_vec<EffectDescriptor>& result) {
@@ -116,10 +140,602 @@
   EXPECT_TRUE(ret.isOk());
 }
 
-int main(int argc, char** argv) {
-  ::testing::AddGlobalTestEnvironment(new AudioEffectHidlEnvironment);
-  ::testing::InitGoogleTest(&argc, argv);
-  int status = RUN_ALL_TESTS();
-  LOG(INFO) << "Test result = " << status;
-  return status;
+// Equalizer effect is required by CDD, but only the type is fixed.
+// This is the same UUID as AudioEffect.EFFECT_TYPE_EQUALIZER in Java.
+static const Uuid EQUALIZER_EFFECT_TYPE = {
+    0x0bed4300, 0xddd6, 0x11db, 0x8f34,
+    std::array<uint8_t, 6>{{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}};
+// Loudness Enhancer effect is required by CDD, but only the type is fixed.
+// This is the same UUID as AudioEffect.EFFECT_TYPE_LOUDNESS_ENHANCER in Java.
+static const Uuid LOUDNESS_ENHANCER_EFFECT_TYPE = {
+    0xfe3199be, 0xaed0, 0x413f, 0x87bb,
+    std::array<uint8_t, 6>{{0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}}};
+
+// The main test class for Audio Effect HIDL HAL.
+class AudioEffectHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+  void SetUp() override {
+    effectsFactory =
+        ::testing::VtsHalHidlTargetTestBase::getService<IEffectsFactory>();
+    ASSERT_NE(nullptr, effectsFactory.get());
+
+    findAndCreateEffect(getEffectType());
+    ASSERT_NE(nullptr, effect.get());
+
+    Return<Result> ret = effect->init();
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_EQ(Result::OK, ret);
+  }
+
+  void TearDown() override {
+    effect.clear();
+    effectsFactory.clear();
+  }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
+
+  virtual Uuid getEffectType() { return EQUALIZER_EFFECT_TYPE; }
+
+  void findAndCreateEffect(const Uuid& type);
+  void findEffectInstance(const Uuid& type, Uuid* uuid);
+  void getChannelCount(uint32_t* channelCount);
+
+  sp<IEffectsFactory> effectsFactory;
+  sp<IEffect> effect;
+};
+
+void AudioEffectHidlTest::findAndCreateEffect(const Uuid& type) {
+  Uuid effectUuid;
+  findEffectInstance(type, &effectUuid);
+  Return<void> ret = effectsFactory->createEffect(
+      effectUuid, 1 /*session*/, 1 /*ioHandle*/,
+      [&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
+        if (r == Result::OK) {
+          effect = result;
+        }
+      });
+  ASSERT_TRUE(ret.isOk());
+}
+
+void AudioEffectHidlTest::findEffectInstance(const Uuid& type, Uuid* uuid) {
+  bool effectFound = false;
+  Return<void> ret = effectsFactory->getAllDescriptors(
+      [&](Result r, const hidl_vec<EffectDescriptor>& result) {
+        if (r == Result::OK) {
+          for (const auto& desc : result) {
+            if (desc.type == type) {
+              effectFound = true;
+              *uuid = desc.uuid;
+              break;
+            }
+          }
+        }
+      });
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_TRUE(effectFound);
+}
+
+void AudioEffectHidlTest::getChannelCount(uint32_t* channelCount) {
+  Result retval;
+  EffectConfig currentConfig;
+  Return<void> ret = effect->getConfig([&](Result r, const EffectConfig& conf) {
+    retval = r;
+    if (r == Result::OK) {
+      currentConfig = conf;
+    }
+  });
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_EQ(Result::OK, retval);
+  ASSERT_TRUE(audio_channel_mask_is_valid(
+      static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels)));
+  *channelCount = audio_channel_count_from_out_mask(
+      static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels));
+}
+
+TEST_F(AudioEffectHidlTest, Close) {
+  description("Verify that an effect can be closed");
+  Return<Result> ret = effect->close();
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, GetDescriptor) {
+  description(
+      "Verify that an effect can return its own descriptor via GetDescriptor");
+  Result retval = Result::NOT_INITIALIZED;
+  Uuid actualType;
+  Return<void> ret =
+      effect->getDescriptor([&](Result r, const EffectDescriptor& desc) {
+        retval = r;
+        if (r == Result::OK) {
+          actualType = desc.type;
+        }
+      });
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, retval);
+  EXPECT_EQ(getEffectType(), actualType);
+}
+
+TEST_F(AudioEffectHidlTest, GetSetConfig) {
+  description(
+      "Verify that it is possible to manipulate effect config via Get / "
+      "SetConfig");
+  Result retval = Result::NOT_INITIALIZED;
+  EffectConfig currentConfig;
+  Return<void> ret = effect->getConfig([&](Result r, const EffectConfig& conf) {
+    retval = r;
+    if (r == Result::OK) {
+      currentConfig = conf;
+    }
+  });
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, retval);
+  Return<Result> ret2 = effect->setConfig(currentConfig, nullptr, nullptr);
+  EXPECT_TRUE(ret2.isOk());
+  EXPECT_EQ(Result::OK, ret2);
+}
+
+// Not generated automatically because AudioBuffer contains
+// instances of hidl_memory which can't be compared properly
+// in general case due to presence of handles.
+//
+// However, in this particular case, handles must not present
+// thus comparison is possible.
+//
+// operator== must be defined in the same namespace as the structures.
+namespace android {
+namespace hardware {
+namespace audio {
+namespace effect {
+namespace V2_0 {
+inline bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs) {
+  return lhs.id == rhs.id && lhs.frameCount == rhs.frameCount &&
+         lhs.data.handle() == nullptr && rhs.data.handle() == nullptr;
+}
+
+inline bool operator==(const EffectBufferConfig& lhs,
+                       const EffectBufferConfig& rhs) {
+  return lhs.buffer == rhs.buffer && lhs.samplingRateHz == rhs.samplingRateHz &&
+         lhs.channels == rhs.channels && lhs.format == rhs.format &&
+         lhs.accessMode == rhs.accessMode && lhs.mask == rhs.mask;
+}
+
+inline bool operator==(const EffectConfig& lhs, const EffectConfig& rhs) {
+  return lhs.inputCfg == rhs.inputCfg && lhs.outputCfg == rhs.outputCfg;
+}
+}  // namespace V2_0
+}  // namespace effect
+}  // namespace audio
+}  // namespace hardware
+}  // namespace android
+
+TEST_F(AudioEffectHidlTest, Reset) {
+  description("Verify that Reset preserves effect configuration");
+  Result retval = Result::NOT_INITIALIZED;
+  EffectConfig originalConfig;
+  Return<void> ret = effect->getConfig([&](Result r, const EffectConfig& conf) {
+    retval = r;
+    if (r == Result::OK) {
+      originalConfig = conf;
+    }
+  });
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_EQ(Result::OK, retval);
+  Return<Result> ret2 = effect->reset();
+  EXPECT_TRUE(ret2.isOk());
+  EXPECT_EQ(Result::OK, ret2);
+  EffectConfig configAfterReset;
+  ret = effect->getConfig([&](Result r, const EffectConfig& conf) {
+    retval = r;
+    if (r == Result::OK) {
+      configAfterReset = conf;
+    }
+  });
+  EXPECT_EQ(originalConfig, configAfterReset);
+}
+
+TEST_F(AudioEffectHidlTest, DisableEnableDisable) {
+  description("Verify Disable -> Enable -> Disable sequence for an effect");
+  Return<Result> ret = effect->disable();
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::INVALID_ARGUMENTS, ret);
+  ret = effect->enable();
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+  ret = effect->disable();
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, SetDevice) {
+  description("Verify that SetDevice works for an output chain effect");
+  Return<Result> ret = effect->setDevice(AudioDevice::OUT_SPEAKER);
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, SetAndGetVolume) {
+  description("Verify that SetAndGetVolume method works for an effect");
+  uint32_t channelCount;
+  getChannelCount(&channelCount);
+  hidl_vec<uint32_t> volumes;
+  volumes.resize(channelCount);
+  for (uint32_t i = 0; i < channelCount; ++i) {
+    volumes[i] = 0;
+  }
+  Result retval = Result::NOT_INITIALIZED;
+  Return<void> ret = effect->setAndGetVolume(
+      volumes, [&](Result r, const hidl_vec<uint32_t>&) { retval = r; });
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, retval);
+}
+
+TEST_F(AudioEffectHidlTest, VolumeChangeNotification) {
+  description("Verify that effect accepts VolumeChangeNotification");
+  uint32_t channelCount;
+  getChannelCount(&channelCount);
+  hidl_vec<uint32_t> volumes;
+  volumes.resize(channelCount);
+  for (uint32_t i = 0; i < channelCount; ++i) {
+    volumes[i] = 0;
+  }
+  Return<Result> ret = effect->volumeChangeNotification(volumes);
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, SetAudioMode) {
+  description("Verify that SetAudioMode works for an effect");
+  Return<Result> ret = effect->setAudioMode(AudioMode::NORMAL);
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, Offload) {
+  description("Verify that calling Offload methods works for an effect");
+  EffectOffloadParameter offloadParam;
+  offloadParam.isOffload = false;
+  offloadParam.ioHandle =
+      static_cast<int>(AudioHandleConsts::AUDIO_IO_HANDLE_NONE);
+  Return<Result> ret = effect->offload(offloadParam);
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, PrepareForProcessing) {
+  description("Verify that PrepareForProcessing method works for an effect");
+  Result retval = Result::NOT_INITIALIZED;
+  Return<void> ret = effect->prepareForProcessing(
+      [&](Result r, const MQDescriptorSync<Result>&) { retval = r; });
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, retval);
+}
+
+TEST_F(AudioEffectHidlTest, SetProcessBuffers) {
+  description("Verify that SetProcessBuffers works for an effect");
+  sp<IAllocator> ashmem = IAllocator::getService("ashmem");
+  ASSERT_NE(nullptr, ashmem.get());
+  bool success = false;
+  AudioBuffer buffer;
+  Return<void> ret =
+      ashmem->allocate(1024, [&](bool s, const hidl_memory& memory) {
+        success = s;
+        if (s) {
+          buffer.data = memory;
+        }
+      });
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_TRUE(success);
+  Return<Result> ret2 = effect->setProcessBuffers(buffer, buffer);
+  EXPECT_TRUE(ret2.isOk());
+  EXPECT_EQ(Result::OK, ret2);
+}
+
+// Testing getConfigReverse, getAuxChannelsConfig,
+// getSupportedAuxChannelsConfigs, setAudioSource, setConfigReverse,
+// setInputDevice doesn't make sense, because normally they are not supported by
+// the Equalizer, but it wouldn't be a problem if some vendor implementation
+// supports them, thus we can't test these methods neither for success, nor for
+// failure.
+
+// command, getParameter, getSupportedConfigsForFeature,
+// getCurrentConfigForFeature, setCurrentConfigForFeature, setParameter are
+// opaque channels between vendor apps and HALs, and can't be meaningfully
+// tested with effects that don't support them.
+
+// The main test class for Equalizer Audio Effect HIDL HAL.
+class EqualizerAudioEffectHidlTest : public AudioEffectHidlTest {
+ public:
+  void SetUp() override {
+    AudioEffectHidlTest::SetUp();
+    equalizer = IEqualizerEffect::castFrom(effect);
+    ASSERT_NE(nullptr, equalizer.get());
+  }
+
+ protected:
+  Uuid getEffectType() override { return EQUALIZER_EFFECT_TYPE; }
+  void getNumBands(uint16_t* numBands);
+  void getLevelRange(int16_t* minLevel, int16_t* maxLevel);
+  void getBandFrequencyRange(uint16_t band, uint32_t* minFreq,
+                             uint32_t* centerFreq, uint32_t* maxFreq);
+  void getPresetCount(size_t* count);
+
+  sp<IEqualizerEffect> equalizer;
+};
+
+void EqualizerAudioEffectHidlTest::getNumBands(uint16_t* numBands) {
+  Result retval = Result::NOT_INITIALIZED;
+  Return<void> ret = equalizer->getNumBands([&](Result r, uint16_t b) {
+    retval = r;
+    if (retval == Result::OK) {
+      *numBands = b;
+    }
+  });
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_EQ(Result::OK, retval);
+}
+
+void EqualizerAudioEffectHidlTest::getLevelRange(int16_t* minLevel,
+                                                 int16_t* maxLevel) {
+  Result retval = Result::NOT_INITIALIZED;
+  Return<void> ret =
+      equalizer->getLevelRange([&](Result r, int16_t min, int16_t max) {
+        retval = r;
+        if (retval == Result::OK) {
+          *minLevel = min;
+          *maxLevel = max;
+        }
+      });
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_EQ(Result::OK, retval);
+}
+
+void EqualizerAudioEffectHidlTest::getBandFrequencyRange(uint16_t band,
+                                                         uint32_t* minFreq,
+                                                         uint32_t* centerFreq,
+                                                         uint32_t* maxFreq) {
+  Result retval = Result::NOT_INITIALIZED;
+  Return<void> ret = equalizer->getBandFrequencyRange(
+      band, [&](Result r, uint32_t min, uint32_t max) {
+        retval = r;
+        if (retval == Result::OK) {
+          *minFreq = min;
+          *maxFreq = max;
+        }
+      });
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_EQ(Result::OK, retval);
+  ret = equalizer->getBandCenterFrequency(band, [&](Result r, uint32_t center) {
+    retval = r;
+    if (retval == Result::OK) {
+      *centerFreq = center;
+    }
+  });
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_EQ(Result::OK, retval);
+}
+
+void EqualizerAudioEffectHidlTest::getPresetCount(size_t* count) {
+  Result retval = Result::NOT_INITIALIZED;
+  Return<void> ret = equalizer->getPresetNames(
+      [&](Result r, const hidl_vec<hidl_string>& names) {
+        retval = r;
+        if (retval == Result::OK) {
+          *count = names.size();
+        }
+      });
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_EQ(Result::OK, retval);
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetNumBands) {
+  description("Verify that Equalizer effect reports at least one band");
+  uint16_t numBands = 0;
+  getNumBands(&numBands);
+  EXPECT_GT(numBands, 0);
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetLevelRange) {
+  description("Verify that Equalizer effect reports adequate band level range");
+  int16_t minLevel = 0x7fff, maxLevel = 0;
+  getLevelRange(&minLevel, &maxLevel);
+  EXPECT_GT(maxLevel, minLevel);
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetSetBandLevel) {
+  description(
+      "Verify that manipulating band levels works for Equalizer effect");
+  uint16_t numBands = 0;
+  getNumBands(&numBands);
+  ASSERT_GT(numBands, 0);
+  int16_t levels[3]{0x7fff, 0, 0};
+  getLevelRange(&levels[0], &levels[2]);
+  ASSERT_GT(levels[2], levels[0]);
+  levels[1] = (levels[2] + levels[0]) / 2;
+  for (uint16_t i = 0; i < numBands; ++i) {
+    for (size_t j = 0; j < ARRAY_SIZE(levels); ++j) {
+      Return<Result> ret = equalizer->setBandLevel(i, levels[j]);
+      EXPECT_TRUE(ret.isOk());
+      EXPECT_EQ(Result::OK, ret);
+      Result retval = Result::NOT_INITIALIZED;
+      int16_t actualLevel;
+      Return<void> ret2 = equalizer->getBandLevel(i, [&](Result r, int16_t l) {
+        retval = r;
+        if (retval == Result::OK) {
+          actualLevel = l;
+        }
+      });
+      EXPECT_TRUE(ret2.isOk());
+      EXPECT_EQ(Result::OK, retval);
+      EXPECT_EQ(levels[j], actualLevel);
+    }
+  }
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetBandCenterFrequencyAndRange) {
+  description(
+      "Verify that Equalizer effect reports adequate band frequency range");
+  uint16_t numBands = 0;
+  getNumBands(&numBands);
+  ASSERT_GT(numBands, 0);
+  for (uint16_t i = 0; i < numBands; ++i) {
+    uint32_t minFreq = 0xffffffff, centerFreq = 0xffffffff,
+             maxFreq = 0xffffffff;
+    getBandFrequencyRange(i, &minFreq, &centerFreq, &maxFreq);
+    // Note: NXP legacy implementation reports "1" as upper bound for last band,
+    // so this check fails.
+    EXPECT_GE(maxFreq, centerFreq);
+    EXPECT_GE(centerFreq, minFreq);
+  }
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetBandForFrequency) {
+  description(
+      "Verify that Equalizer effect supports GetBandForFrequency correctly");
+  uint16_t numBands = 0;
+  getNumBands(&numBands);
+  ASSERT_GT(numBands, 0);
+  for (uint16_t i = 0; i < numBands; ++i) {
+    uint32_t freqs[3]{0, 0, 0};
+    getBandFrequencyRange(i, &freqs[0], &freqs[1], &freqs[2]);
+    // NXP legacy implementation reports "1" as upper bound for last band, some
+    // of the checks fail.
+    for (size_t j = 0; j < ARRAY_SIZE(freqs); ++j) {
+      if (j == 0) {
+        freqs[j]++;
+      }  // Min frequency is an open interval.
+      Result retval = Result::NOT_INITIALIZED;
+      uint16_t actualBand = numBands + 1;
+      Return<void> ret =
+          equalizer->getBandForFrequency(freqs[j], [&](Result r, uint16_t b) {
+            retval = r;
+            if (retval == Result::OK) {
+              actualBand = b;
+            }
+          });
+      EXPECT_TRUE(ret.isOk());
+      EXPECT_EQ(Result::OK, retval);
+      EXPECT_EQ(i, actualBand) << "Frequency: " << freqs[j];
+    }
+  }
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetPresetNames) {
+  description("Verify that Equalizer effect reports at least one preset");
+  size_t presetCount;
+  getPresetCount(&presetCount);
+  EXPECT_GT(presetCount, 0u);
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetSetCurrentPreset) {
+  description(
+      "Verify that manipulating the current preset for Equalizer effect");
+  size_t presetCount;
+  getPresetCount(&presetCount);
+  ASSERT_GT(presetCount, 0u);
+  for (uint16_t i = 0; i < presetCount; ++i) {
+    Return<Result> ret = equalizer->setCurrentPreset(i);
+    EXPECT_TRUE(ret.isOk());
+    EXPECT_EQ(Result::OK, ret);
+    Result retval = Result::NOT_INITIALIZED;
+    uint16_t actualPreset = 0xffff;
+    Return<void> ret2 = equalizer->getCurrentPreset([&](Result r, uint16_t p) {
+      retval = r;
+      if (retval == Result::OK) {
+        actualPreset = p;
+      }
+    });
+    EXPECT_TRUE(ret2.isOk());
+    EXPECT_EQ(Result::OK, retval);
+    EXPECT_EQ(i, actualPreset);
+  }
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetSetAllProperties) {
+  description(
+      "Verify that setting band levels and presets works via Get / "
+      "SetAllProperties for Equalizer effect");
+  using AllProperties =
+      android::hardware::audio::effect::V2_0::IEqualizerEffect::AllProperties;
+  uint16_t numBands = 0;
+  getNumBands(&numBands);
+  ASSERT_GT(numBands, 0);
+  AllProperties props;
+  props.bandLevels.resize(numBands);
+  for (size_t i = 0; i < numBands; ++i) {
+    props.bandLevels[i] = 0;
+  }
+
+  AllProperties actualProps;
+  Result retval = Result::NOT_INITIALIZED;
+
+  // Verify setting of the band levels via properties.
+  props.curPreset = -1;
+  Return<Result> ret = equalizer->setAllProperties(props);
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+  Return<void> ret2 =
+      equalizer->getAllProperties([&](Result r, AllProperties p) {
+        retval = r;
+        if (retval == Result::OK) {
+          actualProps = p;
+        }
+      });
+  EXPECT_TRUE(ret2.isOk());
+  EXPECT_EQ(Result::OK, retval);
+  EXPECT_EQ(props.bandLevels, actualProps.bandLevels);
+
+  // Verify setting of the current preset via properties.
+  props.curPreset = 0;  // Assuming there is at least one preset.
+  ret = equalizer->setAllProperties(props);
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+  ret2 = equalizer->getAllProperties([&](Result r, AllProperties p) {
+    retval = r;
+    if (retval == Result::OK) {
+      actualProps = p;
+    }
+  });
+  EXPECT_TRUE(ret2.isOk());
+  EXPECT_EQ(Result::OK, retval);
+  EXPECT_EQ(props.curPreset, actualProps.curPreset);
+}
+
+// The main test class for Equalizer Audio Effect HIDL HAL.
+class LoudnessEnhancerAudioEffectHidlTest : public AudioEffectHidlTest {
+ public:
+  void SetUp() override {
+    AudioEffectHidlTest::SetUp();
+    enhancer = ILoudnessEnhancerEffect::castFrom(effect);
+    ASSERT_NE(nullptr, enhancer.get());
+  }
+
+ protected:
+  Uuid getEffectType() override { return LOUDNESS_ENHANCER_EFFECT_TYPE; }
+
+  sp<ILoudnessEnhancerEffect> enhancer;
+};
+
+TEST_F(LoudnessEnhancerAudioEffectHidlTest, GetSetTargetGain) {
+  description(
+      "Verify that manipulating the target gain works for Loudness Enhancer "
+      "effect");
+  const int32_t gain = 100;
+  Return<Result> ret = enhancer->setTargetGain(gain);
+  EXPECT_TRUE(ret.isOk());
+  EXPECT_EQ(Result::OK, ret);
+  int32_t actualGain = 0;
+  Result retval;
+  Return<void> ret2 = enhancer->getTargetGain([&](Result r, int32_t g) {
+    retval = r;
+    if (retval == Result::OK) {
+      actualGain = g;
+    }
+  });
+  EXPECT_TRUE(ret2.isOk());
+  EXPECT_EQ(Result::OK, retval);
+  EXPECT_EQ(gain, actualGain);
 }
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index a6507dd..57ea1a3 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -215,11 +215,9 @@
 
   ALOGD("%s vendor library loaded", __func__);
 
-  // Power cycle chip
+  // Power on the controller
 
-  int power_state = BT_VND_PWR_OFF;
-  lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
-  power_state = BT_VND_PWR_ON;
+  int power_state = BT_VND_PWR_ON;
   lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
 
   // Get the UART socket(s)
diff --git a/camera/device/1.0/default/Android.bp b/camera/device/1.0/default/Android.bp
index eec641a..5688fc1 100644
--- a/camera/device/1.0/default/Android.bp
+++ b/camera/device/1.0/default/Android.bp
@@ -1,6 +1,7 @@
 cc_library_shared {
     name: "camera.device@1.0-impl",
     defaults: ["hidl_defaults"],
+    proprietary: true,
     srcs: [
         "CameraDevice.cpp",
     ],
diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp
index 3767e09..e0dc5ff 100644
--- a/camera/device/3.2/default/Android.bp
+++ b/camera/device/3.2/default/Android.bp
@@ -1,6 +1,7 @@
 cc_library_shared {
     name: "camera.device@3.2-impl",
     defaults: ["hidl_defaults"],
+    proprietary: true,
     srcs: ["CameraDevice.cpp",
            "CameraDeviceSession.cpp",
            "convert.cpp"],
diff --git a/configstore/1.0/ISurfaceFlingerConfigs.hal b/configstore/1.0/ISurfaceFlingerConfigs.hal
index 318590d..f9a49ce 100644
--- a/configstore/1.0/ISurfaceFlingerConfigs.hal
+++ b/configstore/1.0/ISurfaceFlingerConfigs.hal
@@ -41,4 +41,33 @@
     vsyncSfEventPhaseOffsetNs() generates (OptionalInt64 value);
 
     useTripleFramebuffer() generates (OptionalBool value);
+
+    /*
+     * Instruct the Render Engine to use EGL_IMG_context_priority hint if
+     * availabe.
+     */
+    useContextPriority() generates(OptionalBool value);
+
+    /*
+     * hasWideColorDisplay indicates that the device has
+     * or can support a wide-color display, e.g. color space
+     * greater than sRGB. Typical display may have same
+     * color primaries as DCI-P3.
+     * Indicate support for this feature by setting
+     * TARGET_HAS_WIDE_COLOR_DISPLAY to true in BoardConfig.mk
+     * This also means that the device is color managed.
+     * A color managed device will use the appropriate
+     * display mode depending on the content on the screen.
+     * Default is sRGB.
+     */
+    hasWideColorDisplay() generates (OptionalBool value);
+
+    /*
+     * hwHdrDisplay indicates that the device has
+     * or can support an HDR (High Dynamic Range) display.
+     * Typically an HDR display is also wide-color.
+     * Indicate support for this feature by setting
+     * TARGET_HAS_HDR_DISPLAY to true in BoardConfig.mk
+     */
+    hasHDRDisplay() generates (OptionalBool value);
 };
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.cpp b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
index f73ecb4..035479c 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
@@ -39,6 +39,36 @@
     return Void();
 }
 
+Return<void> SurfaceFlingerConfigs::useContextPriority(useContextPriority_cb _hidl_cb) {
+#ifdef USE_CONTEXT_PRIORITY
+    _hidl_cb({true, USE_CONTEXT_PRIORITY});
+    LOG(INFO) << "SurfaceFlinger useContextPriority=" << USE_CONTEXT_PRIORITY;
+#else
+    _hidl_cb({false, false});
+#endif
+    return Void();
+}
+
+Return<void> SurfaceFlingerConfigs::hasWideColorDisplay(hasWideColorDisplay_cb _hidl_cb) {
+    bool value = false;
+#ifdef HAS_WIDE_COLOR_DISPLAY
+    value = true;
+#endif
+    _hidl_cb({true, value});
+    LOG(INFO) << "SurfaceFlinger Display: " << (value ? "Wide Color" : "Standard Color");
+    return Void();
+}
+
+Return<void> SurfaceFlingerConfigs::hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) {
+    bool value = false;
+#ifdef HAS_HDR_DISPLAY
+    value = true;
+#endif
+    _hidl_cb({true, value});
+    LOG(INFO) << "SurfaceFlinger Display: " << (value ? "HDR" : "SDR");
+    return Void();
+}
+
 // Methods from ::android::hidl::base::V1_0::IBase follow.
 
 ISurfaceFlingerConfigs* HIDL_FETCH_ISurfaceFlingerConfigs(const char* /* name */) {
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.h b/configstore/1.0/default/SurfaceFlingerConfigs.h
index bbb61d6..aa7fb8b 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.h
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.h
@@ -27,6 +27,9 @@
     Return<void> vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) override;
     Return<void> vsyncSfEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) override;
     Return<void> useTripleFramebuffer(useTripleFramebuffer_cb _hidl_cb) override;
+    Return<void> useContextPriority(useContextPriority_cb _hidl_cb) override;
+    Return<void> hasWideColorDisplay(hasWideColorDisplay_cb _hidl_cb) override;
+    Return<void> hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) override;
 
     // Methods from ::android::hidl::base::V1_0::IBase follow.
 
diff --git a/configstore/1.0/default/surfaceflinger.mk b/configstore/1.0/default/surfaceflinger.mk
index 49314d7..8ee3686 100644
--- a/configstore/1.0/default/surfaceflinger.mk
+++ b/configstore/1.0/default/surfaceflinger.mk
@@ -12,3 +12,20 @@
 ifeq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),3)
     LOCAL_CFLAGS += -DUSE_TRIPLE_FRAMEBUFFER
 endif
+
+ifeq ($(TARGET_BOARD_PLATFORM),omap4)
+    LOCAL_CFLAGS += -DUSE_CONTEXT_PRIORITY=1
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM),s5pc110)
+    LOCAL_CFLAGS += -DUSE_CONTEXT_PRIORITY=1
+endif
+
+ifeq ($(TARGET_HAS_WIDE_COLOR_DISPLAY),true)
+    LOCAL_CFLAGS += -DHAS_WIDE_COLOR_DISPLAY
+endif
+
+ifeq ($(TARGET_HAS_HDR_DISPLAY),true)
+    LOCAL_CFLAGS += -DHAS_HDR_DISPLAY
+endif
+
diff --git a/graphics/common/1.0/types.hal b/graphics/common/1.0/types.hal
index 1ddd892..dfecec1 100644
--- a/graphics/common/1.0/types.hal
+++ b/graphics/common/1.0/types.hal
@@ -1354,10 +1354,12 @@
    *
    * PC/Internet (sRGB) Gamma Correction (GC):
    *
-   *  if Vlinear ≤ 0.0031308
+   *  if Vlinear ≤ 0.0030186
    *    Vnonlinear = 12.92 * Vlinear
    *  else
    *    Vnonlinear = 1.055 * (Vlinear)^(1/2.4) – 0.055
+   *
+   * Note: In most cases sRGB transfer function will be fine.
    */
   DISPLAY_P3 = 9
 };
diff --git a/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp b/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp
index afda739..b0aef4b 100644
--- a/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp
+++ b/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp
@@ -138,7 +138,7 @@
         } while (mClients.valueFor(*modelId) != 0 && *modelId != 0);
     }
     LOG_ALWAYS_FATAL_IF(*modelId == 0,
-                        "wrap around in sound model IDs, num loaded models %d", mClients.size());
+                        "wrap around in sound model IDs, num loaded models %zu", mClients.size());
 
     client = new SoundModelClient(*modelId, callback, cookie);
 
diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp
index 692edda..16018ac 100644
--- a/tests/msgq/1.0/default/Android.bp
+++ b/tests/msgq/1.0/default/Android.bp
@@ -1,3 +1,18 @@
+//
+// Copyright (C) 2017 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.
+
 cc_library_shared {
     name: "android.hardware.tests.msgq@1.0-impl",
     defaults: ["hidl_defaults"],
@@ -5,6 +20,7 @@
     proprietary: true,
     srcs: [
         "TestMsgQ.cpp",
+        "BenchmarkMsgQ.cpp"
     ],
     shared_libs: [
         "libbase",
@@ -18,3 +34,35 @@
         "android.hidl.base@1.0",
     ],
 }
+
+cc_test {
+    name: "android.hardware.tests.msgq@1.0-service-benchmark",
+    srcs: ["mq_benchmark_service.cpp"],
+    gtest: false,
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.tests.msgq@1.0"
+    ],
+}
+
+cc_test {
+    name: "android.hardware.tests.msgq@1.0-service-test",
+    srcs: ["mq_test_service.cpp"],
+    gtest: false,
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.tests.msgq@1.0"
+    ],
+}
diff --git a/tests/msgq/1.0/default/BenchmarkMsgQ.cpp b/tests/msgq/1.0/default/BenchmarkMsgQ.cpp
new file mode 100644
index 0000000..43e6fcc
--- /dev/null
+++ b/tests/msgq/1.0/default/BenchmarkMsgQ.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BenchmarkMsgQ.h"
+#include <iostream>
+#include <thread>
+#include <fmq/MessageQueue.h>
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace msgq {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ follow.
+Return<void> BenchmarkMsgQ::configureClientInboxSyncReadWrite(
+        configureClientInboxSyncReadWrite_cb _hidl_cb) {
+    static constexpr size_t kNumElementsInQueue = 16 * 1024;
+    mFmqOutbox = new (std::nothrow) android::hardware::MessageQueue<uint8_t,
+               kSynchronizedReadWrite>(kNumElementsInQueue);
+    if (mFmqOutbox == nullptr) {
+        _hidl_cb(false /* ret */, android::hardware::MQDescriptorSync<uint8_t>(
+                std::vector<android::hardware::GrantorDescriptor>(),
+                nullptr /* nhandle */, 0 /* size */));
+    } else {
+        _hidl_cb(true /* ret */, *mFmqOutbox->getDesc());
+    }
+
+    return Void();
+}
+
+Return<void> BenchmarkMsgQ::configureClientOutboxSyncReadWrite(
+        configureClientOutboxSyncReadWrite_cb _hidl_cb) {
+    static constexpr size_t kNumElementsInQueue = 16 * 1024;
+    mFmqInbox = new (std::nothrow) android::hardware::MessageQueue<uint8_t,
+              kSynchronizedReadWrite>(kNumElementsInQueue);
+    if ((mFmqInbox == nullptr) || (mFmqInbox->isValid() == false)) {
+        _hidl_cb(false /* ret */, android::hardware::MQDescriptorSync<uint8_t>(
+                std::vector<android::hardware::GrantorDescriptor>(),
+                nullptr /* nhandle */, 0 /* size */));
+    } else {
+        _hidl_cb(true /* ret */, *mFmqInbox->getDesc());
+    }
+
+    return Void();
+}
+
+Return<bool> BenchmarkMsgQ::requestWrite(int32_t count) {
+    uint8_t* data = new (std::nothrow) uint8_t[count];
+    for (int i = 0; i < count; i++) {
+        data[i] = i;
+    }
+    bool result = mFmqOutbox->write(data, count);
+    delete[] data;
+    return result;
+}
+
+Return<bool> BenchmarkMsgQ::requestRead(int32_t count) {
+    uint8_t* data = new (std::nothrow) uint8_t[count];
+    bool result = mFmqInbox->read(data, count);
+    delete[] data;
+    return result;
+}
+
+Return<void> BenchmarkMsgQ::benchmarkPingPong(uint32_t numIter) {
+    std::thread(QueuePairReadWrite<kSynchronizedReadWrite>, mFmqInbox,
+                mFmqOutbox, numIter)
+            .detach();
+    return Void();
+}
+
+Return<void> BenchmarkMsgQ::benchmarkServiceWriteClientRead(uint32_t numIter) {
+    if (mTimeData) delete[] mTimeData;
+    mTimeData = new (std::nothrow) int64_t[numIter];
+    std::thread(QueueWriter<kSynchronizedReadWrite>, mFmqOutbox,
+                mTimeData, numIter).detach();
+    return Void();
+}
+
+Return<void> BenchmarkMsgQ::sendTimeData(const hidl_vec<int64_t>& clientRcvTimeArray) {
+    int64_t accumulatedTime = 0;
+
+    for (uint32_t i = 0; i < clientRcvTimeArray.size(); i++) {
+        std::chrono::time_point<std::chrono::high_resolution_clock>
+                clientRcvTime((std::chrono::high_resolution_clock::duration(
+                        clientRcvTimeArray[i])));
+        std::chrono::time_point<std::chrono::high_resolution_clock>serverSendTime(
+                (std::chrono::high_resolution_clock::duration(mTimeData[i])));
+        accumulatedTime += static_cast<int64_t>(
+                std::chrono::duration_cast<std::chrono::nanoseconds>(clientRcvTime -
+                                                                     serverSendTime).count());
+    }
+
+    accumulatedTime /= clientRcvTimeArray.size();
+    std::cout << "Average service to client write to read delay::"
+         << accumulatedTime << "ns" << std::endl;
+    return Void();
+}
+
+template <MQFlavor flavor>
+void BenchmarkMsgQ::QueueWriter(android::hardware::MessageQueue<uint8_t, flavor>* mFmqOutbox,
+                                int64_t* mTimeData,
+                                uint32_t numIter) {
+    uint8_t data[kPacketSize64];
+    uint32_t numWrites = 0;
+
+    while (numWrites < numIter) {
+        do {
+            mTimeData[numWrites] =
+                    std::chrono::high_resolution_clock::now().time_since_epoch().count();
+        } while (mFmqOutbox->write(data, kPacketSize64) == false);
+        numWrites++;
+    }
+}
+
+template <MQFlavor flavor>
+void BenchmarkMsgQ::QueuePairReadWrite(
+        android::hardware::MessageQueue<uint8_t, flavor>* mFmqInbox,
+        android::hardware::MessageQueue<uint8_t, flavor>* mFmqOutbox,
+        uint32_t numIter) {
+    uint8_t data[kPacketSize64];
+    uint32_t numRoundTrips = 0;
+
+    while (numRoundTrips < numIter) {
+        while (mFmqInbox->read(data, kPacketSize64) == false)
+            ;
+        while (mFmqOutbox->write(data, kPacketSize64) == false)
+            ;
+        numRoundTrips++;
+    }
+}
+
+IBenchmarkMsgQ* HIDL_FETCH_IBenchmarkMsgQ(const char* /* name */) {
+    return new BenchmarkMsgQ();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace msgq
+}  // namespace tests
+}  // namespace hardware
+}  // namespace android
diff --git a/tests/msgq/1.0/default/BenchmarkMsgQ.h b/tests/msgq/1.0/default/BenchmarkMsgQ.h
new file mode 100644
index 0000000..2cbe93c
--- /dev/null
+++ b/tests/msgq/1.0/default/BenchmarkMsgQ.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_TESTS_MSGQ_V1_0_BENCHMARKMSGQ_H
+#define ANDROID_HARDWARE_TESTS_MSGQ_V1_0_BENCHMARKMSGQ_H
+
+#include <android/hardware/tests/msgq/1.0/IBenchmarkMsgQ.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <fmq/MessageQueue.h>
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace msgq {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using android::hardware::kSynchronizedReadWrite;
+using android::hardware::MQFlavor;
+
+struct BenchmarkMsgQ : public IBenchmarkMsgQ {
+    /*
+     * The various packet sizes used are as follows.
+     */
+    enum PacketSizes {
+        kPacketSize64 = 64,
+        kPacketSize128 = 128,
+        kPacketSize256 = 256,
+        kPacketSize512 = 512,
+        kPacketSize1024 = 1024
+    };
+    // Methods from ::android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ follow.
+    Return<void> configureClientInboxSyncReadWrite(configureClientInboxSyncReadWrite_cb _hidl_cb) override;
+    Return<void> configureClientOutboxSyncReadWrite(configureClientOutboxSyncReadWrite_cb _hidl_cb) override;
+    Return<bool> requestWrite(int32_t count) override;
+    Return<bool> requestRead(int32_t count) override;
+    Return<void> benchmarkPingPong(uint32_t numIter) override;
+    Return<void> benchmarkServiceWriteClientRead(uint32_t numIter) override;
+    Return<void> sendTimeData(const hidl_vec<int64_t>& timeData) override;
+
+     /*
+     * This method writes numIter packets into the mFmqOutbox queue
+     * and notes the time before each write in the mTimeData array. It will
+     * be used to calculate the average server to client write to read delay.
+     */
+    template <MQFlavor flavor>
+    static void QueueWriter(android::hardware::MessageQueue<uint8_t, flavor>*
+                     mFmqOutbox, int64_t* mTimeData, uint32_t numIter);
+    /*
+     * The method reads a packet from the inbox queue and writes the same
+     * into the outbox queue. The client will calculate the average time taken
+     * for each iteration which consists of two write and two read operations.
+     */
+    template <MQFlavor flavor>
+    static void QueuePairReadWrite(
+            android::hardware::MessageQueue<uint8_t, flavor>* mFmqInbox,
+            android::hardware::MessageQueue<uint8_t, flavor>* mFmqOutbox,
+            uint32_t numIter);
+
+private:
+    android::hardware::MessageQueue<uint8_t, kSynchronizedReadWrite>* mFmqInbox;
+    android::hardware::MessageQueue<uint8_t, kSynchronizedReadWrite>* mFmqOutbox;
+    int64_t* mTimeData;
+};
+
+extern "C" IBenchmarkMsgQ* HIDL_FETCH_IBenchmarkMsgQ(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace msgq
+}  // namespace tests
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TESTS_MSGQ_V1_0_BENCHMARKMSGQ_H
diff --git a/tests/msgq/1.0/default/TestMsgQ.cpp b/tests/msgq/1.0/default/TestMsgQ.cpp
index 7cc4f5b..6fd4fc6 100644
--- a/tests/msgq/1.0/default/TestMsgQ.cpp
+++ b/tests/msgq/1.0/default/TestMsgQ.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #include "TestMsgQ.h"
 
 namespace android {
diff --git a/tests/msgq/1.0/default/TestMsgQ.h b/tests/msgq/1.0/default/TestMsgQ.h
index 760d931..86e4ac4 100644
--- a/tests/msgq/1.0/default/TestMsgQ.h
+++ b/tests/msgq/1.0/default/TestMsgQ.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #ifndef ANDROID_HARDWARE_TESTS_MSGQ_V1_0_TESTMSGQ_H
 #define ANDROID_HARDWARE_TESTS_MSGQ_V1_0_TESTMSGQ_H
 
diff --git a/tests/msgq/1.0/default/mq_benchmark_service.cpp b/tests/msgq/1.0/default/mq_benchmark_service.cpp
new file mode 100644
index 0000000..b9be81b
--- /dev/null
+++ b/tests/msgq/1.0/default/mq_benchmark_service.cpp
@@ -0,0 +1,28 @@
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#define LOG_TAG "FMQ_Benchmarks"
+
+#include <android/hardware/tests/msgq/1.0/IBenchmarkMsgQ.h>
+
+#include <hidl/LegacySupport.h>
+
+using android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+    return defaultPassthroughServiceImplementation<IBenchmarkMsgQ>();
+}
diff --git a/tests/msgq/1.0/default/mq_test_service.cpp b/tests/msgq/1.0/default/mq_test_service.cpp
new file mode 100644
index 0000000..b5cb662
--- /dev/null
+++ b/tests/msgq/1.0/default/mq_test_service.cpp
@@ -0,0 +1,28 @@
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#define LOG_TAG "FMQ_UnitTests"
+
+#include <android/hardware/tests/msgq/1.0/ITestMsgQ.h>
+
+#include <hidl/LegacySupport.h>
+
+using android::hardware::tests::msgq::V1_0::ITestMsgQ;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+    return defaultPassthroughServiceImplementation<ITestMsgQ>();
+}
diff --git a/tv/input/1.0/default/TvInput.cpp b/tv/input/1.0/default/TvInput.cpp
index 6fcb2e5..0bc6401 100644
--- a/tv/input/1.0/default/TvInput.cpp
+++ b/tv/input/1.0/default/TvInput.cpp
@@ -158,6 +158,7 @@
         tvInputEvent.deviceInfo.type = static_cast<TvInputType>(
                 event->device_info.type);
         tvInputEvent.deviceInfo.portId = event->device_info.hdmi.port_id;
+        tvInputEvent.deviceInfo.cableConnectionStatus = CableConnectionStatus::UNKNOWN;
         // TODO: Ensure the legacy audio type code is the same once audio HAL default
         // implementation is ready.
         tvInputEvent.deviceInfo.audioType = static_cast<AudioDevice>(
diff --git a/tv/input/1.0/types.hal b/tv/input/1.0/types.hal
index 6852c70..55eb6ad 100644
--- a/tv/input/1.0/types.hal
+++ b/tv/input/1.0/types.hal
@@ -40,14 +40,27 @@
     DISPLAY_PORT = 10,
 };
 
+/*
+ * Status of cable connection.
+ * This status is for devices having availability to detect the cable in a mechanical way,
+ * regardless of whether the connected external device is electrically on or not.
+ * If the device does not have such capability, you must use UNKNOWN.
+ */
+enum CableConnectionStatus : int32_t {
+    UNKNOWN = 0,
+    CONNECTED = 1,
+    DISCONNECTED = 2,
+};
+
 struct TvInputDeviceInfo {
     int32_t deviceId;
     TvInputType type;
-    uint32_t portId;          // HDMI port ID number. e.g. 2 for HDMI 2
-    AudioDevice audioType;    // Audio device type. e.g AudioDevice::IN_HDMI
-    uint8_t[32] audioAddress; // Audio device address. "" if N/A. If the text
-                              // length is less than 32, the remaining part
-                              // must be filled with 0s.
+    uint32_t portId;                             // HDMI port ID number. e.g. 2 for HDMI 2
+    CableConnectionStatus cableConnectionStatus; // Cable connection status.
+    AudioDevice audioType;                       // Audio device type. e.g AudioDevice::IN_HDMI
+    uint8_t[32] audioAddress;                    // Audio device address. "" if N/A. If the text
+                                                 // length is less than 32, the remaining part
+                                                 // must be filled with 0s.
 };
 
 enum TvInputEventType : int32_t {
diff --git a/wifi/1.0/default/Android.mk b/wifi/1.0/default/Android.mk
index e84c1c5..cc5e1c6 100644
--- a/wifi/1.0/default/Android.mk
+++ b/wifi/1.0/default/Android.mk
@@ -46,7 +46,8 @@
     libnl \
     libutils \
     libwifi-hal \
-    libwifi-system
+    libwifi-system \
+    libcld80211
 LOCAL_WHOLE_STATIC_LIBRARIES := $(LIB_WIFI_HAL)
 LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc
 include $(BUILD_EXECUTABLE)
diff --git a/wifi/1.0/default/hidl_struct_util.cpp b/wifi/1.0/default/hidl_struct_util.cpp
index a89f8c0..fb93c5a 100644
--- a/wifi/1.0/default/hidl_struct_util.cpp
+++ b/wifi/1.0/default/hidl_struct_util.cpp
@@ -706,11 +706,17 @@
   hidl_stats->iface.wmeVoPktStats.retries =
       legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
   // radio legacy_stats conversion.
-  hidl_stats->radio.onTimeInMs = legacy_stats.radio.on_time;
-  hidl_stats->radio.txTimeInMs = legacy_stats.radio.tx_time;
-  hidl_stats->radio.rxTimeInMs = legacy_stats.radio.rx_time;
-  hidl_stats->radio.onTimeInMsForScan = legacy_stats.radio.on_time_scan;
-  hidl_stats->radio.txTimeInMsPerLevel = legacy_stats.radio_tx_time_per_levels;
+  std::vector<StaLinkLayerRadioStats> hidl_radios_stats;
+  for (const auto& legacy_radio_stats : legacy_stats.radios) {
+    StaLinkLayerRadioStats hidl_radio_stats;
+    hidl_radio_stats.onTimeInMs = legacy_radio_stats.stats.on_time;
+    hidl_radio_stats.txTimeInMs = legacy_radio_stats.stats.tx_time;
+    hidl_radio_stats.rxTimeInMs = legacy_radio_stats.stats.rx_time;
+    hidl_radio_stats.onTimeInMsForScan = legacy_radio_stats.stats.on_time_scan;
+    hidl_radio_stats.txTimeInMsPerLevel = legacy_radio_stats.tx_time_per_levels;
+    hidl_radios_stats.push_back(hidl_radio_stats);
+  }
+  hidl_stats->radios = hidl_radios_stats;
   // Timestamp in the HAL wrapper here since it's not provided in the legacy
   // HAL API.
   hidl_stats->timeStampInMs = uptimeMillis();
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
index f902e64..5fc0228 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -601,33 +601,37 @@
   LinkLayerStats link_stats{};
   LinkLayerStats* link_stats_ptr = &link_stats;
 
-  on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
-      wifi_request_id /* id */,
-      wifi_iface_stat* iface_stats_ptr,
-      int num_radios,
-      wifi_radio_stat* radio_stats_ptr) {
-    if (iface_stats_ptr != nullptr) {
-      link_stats_ptr->iface = *iface_stats_ptr;
-      link_stats_ptr->iface.num_peers = 0;
-    } else {
-      LOG(ERROR) << "Invalid iface stats in link layer stats";
-    }
-    if (num_radios == 1 && radio_stats_ptr != nullptr) {
-      link_stats_ptr->radio = *radio_stats_ptr;
-      // Copy over the tx level array to the separate vector.
-      if (radio_stats_ptr->num_tx_levels > 0 &&
-          radio_stats_ptr->tx_time_per_levels != nullptr) {
-        link_stats_ptr->radio_tx_time_per_levels.assign(
-            radio_stats_ptr->tx_time_per_levels,
-            radio_stats_ptr->tx_time_per_levels +
-                radio_stats_ptr->num_tx_levels);
-      }
-      link_stats_ptr->radio.num_tx_levels = 0;
-      link_stats_ptr->radio.tx_time_per_levels = nullptr;
-    } else {
-      LOG(ERROR) << "Invalid radio stats in link layer stats";
-    }
-  };
+  on_link_layer_stats_result_internal_callback =
+      [&link_stats_ptr](wifi_request_id /* id */,
+                        wifi_iface_stat* iface_stats_ptr,
+                        int num_radios,
+                        wifi_radio_stat* radio_stats_ptr) {
+        if (iface_stats_ptr != nullptr) {
+          link_stats_ptr->iface = *iface_stats_ptr;
+          link_stats_ptr->iface.num_peers = 0;
+        } else {
+          LOG(ERROR) << "Invalid iface stats in link layer stats";
+        }
+        if (num_radios <= 0 || radio_stats_ptr == nullptr) {
+          LOG(ERROR) << "Invalid radio stats in link layer stats";
+          return;
+        }
+        for (int i = 0; i < num_radios; i++) {
+          LinkLayerRadioStats radio;
+          radio.stats = radio_stats_ptr[i];
+          // Copy over the tx level array to the separate vector.
+          if (radio_stats_ptr[i].num_tx_levels > 0 &&
+              radio_stats_ptr[i].tx_time_per_levels != nullptr) {
+            radio.tx_time_per_levels.assign(
+                radio_stats_ptr[i].tx_time_per_levels,
+                radio_stats_ptr[i].tx_time_per_levels +
+                    radio_stats_ptr[i].num_tx_levels);
+          }
+          radio.stats.num_tx_levels = 0;
+          radio.stats.tx_time_per_levels = nullptr;
+          link_stats_ptr->radios.push_back(radio);
+        }
+      };
 
   wifi_error status = global_func_table_.wifi_get_link_stats(
       0, wlan_interface_handle_, {onSyncLinkLayerStatsResult});
diff --git a/wifi/1.0/default/wifi_legacy_hal.h b/wifi/1.0/default/wifi_legacy_hal.h
index c8fd5bd..576dfe6 100644
--- a/wifi/1.0/default/wifi_legacy_hal.h
+++ b/wifi/1.0/default/wifi_legacy_hal.h
@@ -49,10 +49,14 @@
 // The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in
 // |wifi_radio_stat| structure in the legacy HAL API. Separate that out
 // into a separate return element to avoid passing pointers around.
+struct LinkLayerRadioStats {
+  wifi_radio_stat stats;
+  std::vector<uint32_t> tx_time_per_levels;
+};
+
 struct LinkLayerStats {
   wifi_iface_stat iface;
-  wifi_radio_stat radio;
-  std::vector<uint32_t> radio_tx_time_per_levels;
+  std::vector<LinkLayerRadioStats> radios;
 };
 #pragma GCC diagnostic pop
 
@@ -285,7 +289,7 @@
   // Opaque handle to be used for all wlan0 interface specific operations.
   wifi_interface_handle wlan_interface_handle_;
   // Flag to indicate if we have initiated the cleanup of legacy HAL.
-  bool awaiting_event_loop_termination_;
+  std::atomic<bool> awaiting_event_loop_termination_;
   // Flag to indicate if the legacy HAL has been started.
   bool is_started_;
   wifi_system::InterfaceTool iface_tool_;
diff --git a/wifi/1.0/types.hal b/wifi/1.0/types.hal
index d90d5be..d3845c9 100644
--- a/wifi/1.0/types.hal
+++ b/wifi/1.0/types.hal
@@ -143,7 +143,7 @@
 /**
  * TimeStamp in milliseconds (ms).
  */
-typedef uint32_t TimeStampInMs;
+typedef uint64_t TimeStampInMs;
 
 /**
  * TimeStamp in microseconds (us).
@@ -478,7 +478,7 @@
  */
 struct StaLinkLayerStats {
   StaLinkLayerIfaceStats iface;
-  StaLinkLayerRadioStats radio;
+  vec<StaLinkLayerRadioStats> radios;
   /**
    * TimeStamp for each stats sample.
    * This is the absolute milliseconds from boot when these stats were
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
index eab338b..9403e98 100644
--- a/wifi/1.0/vts/functional/Android.bp
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -14,17 +14,32 @@
 // limitations under the License.
 //
 
+cc_library_static {
+    name: "VtsHalWifiV1_0TargetTestUtil",
+    srcs: [
+        "VtsHalWifiV1_0TargetTest.cpp",
+        "wifi_hidl_call_util_selftest.cpp",
+        "wifi_hidl_test.cpp",
+        "wifi_hidl_test_utils.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.wifi@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+}
+
 cc_test {
     name: "VtsHalWifiV1_0TargetTest",
     defaults: ["hidl_defaults"],
     srcs: [
-        "VtsHalWifiV1_0TargetTest.cpp",
         "wifi_ap_iface_hidl_test.cpp",
         "wifi_chip_hidl_test.cpp",
-        "wifi_hidl_call_util_selftest.cpp",
-        "wifi_hidl_test.cpp",
-        "wifi_hidl_test_utils.cpp",
-        "wifi_nan_iface_hidl_test.cpp",
         "wifi_p2p_iface_hidl_test.cpp",
         "wifi_rtt_controller_hidl_test.cpp",
         "wifi_sta_iface_hidl_test.cpp"],
@@ -38,7 +53,28 @@
         "libutils",
         "android.hardware.wifi@1.0",
     ],
-    static_libs: ["VtsHalHidlTargetTestBase"],
+    static_libs: ["VtsHalWifiV1_0TargetTestUtil", "VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
+
+cc_test {
+    name: "VtsHalWifiNanV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["wifi_nan_iface_hidl_test.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.wifi@1.0",
+    ],
+    static_libs: ["VtsHalWifiV1_0TargetTestUtil", "VtsHalHidlTargetTestBase"],
     cflags: [
         "-O0",
         "-g",