Merge changes I1610beb9,Ibcf607d0

* changes:
  Fix typo CELCIUS -> CELSIUS in Vehicle HAL
  Fix config map in default Vehicle HAL impl
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..e6575b0 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)
@@ -250,10 +248,9 @@
         new hci::MctProtocol(fd_list, intercept_events, acl_cb);
     fd_watcher_.WatchFdForNonBlockingReads(
         fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
-    if (fd_count >= CH_ACL_IN)
-      fd_watcher_.WatchFdForNonBlockingReads(
-          fd_list[CH_ACL_IN],
-          [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
+    fd_watcher_.WatchFdForNonBlockingReads(
+        fd_list[CH_ACL_IN],
+        [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
     hci_ = mct_hci;
   }
 
@@ -268,13 +265,6 @@
 }
 
 void VendorInterface::Close() {
-  // These callbacks may send HCI events (vendor-dependent), so make sure to
-  // StopWatching the file descriptor after this.
-  if (lib_interface_ != nullptr) {
-    bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
-    lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
-  }
-
   fd_watcher_.StopWatchingFileDescriptors();
 
   if (hci_ != nullptr) {
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/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp
index ad9f0b8..8701ec1 100644
--- a/camera/provider/2.4/default/CameraProvider.cpp
+++ b/camera/provider/2.4/default/CameraProvider.cpp
@@ -183,6 +183,12 @@
     }
     ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
 
+    // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
+    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
+    if (!setUpVendorTags()) {
+        ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
+    }
+
     // Setup callback now because we are going to try openLegacy next
     err = mModule->setCallbacks(this);
     if (err != OK) {
@@ -225,11 +231,6 @@
         }
     }
 
-    // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
-    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
-    if (!setUpVendorTags()) {
-        ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
-    }
     return false; // mInitFailed
 }
 
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index f1215b8..a0be5cb 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -17,7 +17,8 @@
 cc_test {
     name: "VtsHalCameraProviderV2_4TargetTest",
     defaults: ["hidl_defaults"],
-    srcs: ["VtsHalCameraProviderV2_4TargetTest.cpp"],
+    srcs: ["VtsHalCameraProviderV2_4TargetTest.cpp",
+           "CameraParameters.cpp" ],
     shared_libs: [
         "liblog",
         "libhidlbase",
@@ -26,7 +27,10 @@
         "libutils",
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@1.0",
         "libcamera_metadata",
+        "libbinder",
+        "libgui",
         "libui"
     ],
     static_libs: ["VtsHalHidlTargetTestBase"],
diff --git a/camera/provider/2.4/vts/functional/CameraParameters.cpp b/camera/provider/2.4/vts/functional/CameraParameters.cpp
new file mode 100644
index 0000000..0285154
--- /dev/null
+++ b/camera/provider/2.4/vts/functional/CameraParameters.cpp
@@ -0,0 +1,537 @@
+/*
+**
+** Copyright 2008, 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 "CameraParams"
+#include <utils/Log.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include "CameraParameters.h"
+#include <system/graphics.h>
+
+namespace android {
+// Parameter keys to communicate between camera application and driver.
+const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
+const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values";
+const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values";
+const char CameraParameters::KEY_PREVIEW_FPS_RANGE[] = "preview-fps-range";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE[] = "preview-fps-range-values";
+const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size";
+const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values";
+const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format";
+const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height";
+const char CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality";
+const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality";
+const char CameraParameters::KEY_ROTATION[] = "rotation";
+const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude";
+const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude";
+const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude";
+const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp";
+const char CameraParameters::KEY_GPS_PROCESSING_METHOD[] = "gps-processing-method";
+const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance";
+const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values";
+const char CameraParameters::KEY_EFFECT[] = "effect";
+const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values";
+const char CameraParameters::KEY_ANTIBANDING[] = "antibanding";
+const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values";
+const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode";
+const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values";
+const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode";
+const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
+const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
+const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
+const char CameraParameters::KEY_MAX_NUM_FOCUS_AREAS[] = "max-num-focus-areas";
+const char CameraParameters::KEY_FOCUS_AREAS[] = "focus-areas";
+const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length";
+const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
+const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
+const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation";
+const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
+const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
+const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK[] = "auto-exposure-lock";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[] = "auto-exposure-lock-supported";
+const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK[] = "auto-whitebalance-lock";
+const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[] = "auto-whitebalance-lock-supported";
+const char CameraParameters::KEY_MAX_NUM_METERING_AREAS[] = "max-num-metering-areas";
+const char CameraParameters::KEY_METERING_AREAS[] = "metering-areas";
+const char CameraParameters::KEY_ZOOM[] = "zoom";
+const char CameraParameters::KEY_MAX_ZOOM[] = "max-zoom";
+const char CameraParameters::KEY_ZOOM_RATIOS[] = "zoom-ratios";
+const char CameraParameters::KEY_ZOOM_SUPPORTED[] = "zoom-supported";
+const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported";
+const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances";
+const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format";
+const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size";
+const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
+const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
+const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
+const char CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED[] = "video-snapshot-supported";
+const char CameraParameters::KEY_VIDEO_STABILIZATION[] = "video-stabilization";
+const char CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED[] = "video-stabilization-supported";
+const char CameraParameters::KEY_LIGHTFX[] = "light-fx";
+
+const char CameraParameters::TRUE[] = "true";
+const char CameraParameters::FALSE[] = "false";
+const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
+
+// Values for white balance settings.
+const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
+const char CameraParameters::WHITE_BALANCE_INCANDESCENT[] = "incandescent";
+const char CameraParameters::WHITE_BALANCE_FLUORESCENT[] = "fluorescent";
+const char CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT[] = "warm-fluorescent";
+const char CameraParameters::WHITE_BALANCE_DAYLIGHT[] = "daylight";
+const char CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT[] = "cloudy-daylight";
+const char CameraParameters::WHITE_BALANCE_TWILIGHT[] = "twilight";
+const char CameraParameters::WHITE_BALANCE_SHADE[] = "shade";
+
+// Values for effect settings.
+const char CameraParameters::EFFECT_NONE[] = "none";
+const char CameraParameters::EFFECT_MONO[] = "mono";
+const char CameraParameters::EFFECT_NEGATIVE[] = "negative";
+const char CameraParameters::EFFECT_SOLARIZE[] = "solarize";
+const char CameraParameters::EFFECT_SEPIA[] = "sepia";
+const char CameraParameters::EFFECT_POSTERIZE[] = "posterize";
+const char CameraParameters::EFFECT_WHITEBOARD[] = "whiteboard";
+const char CameraParameters::EFFECT_BLACKBOARD[] = "blackboard";
+const char CameraParameters::EFFECT_AQUA[] = "aqua";
+
+// Values for antibanding settings.
+const char CameraParameters::ANTIBANDING_AUTO[] = "auto";
+const char CameraParameters::ANTIBANDING_50HZ[] = "50hz";
+const char CameraParameters::ANTIBANDING_60HZ[] = "60hz";
+const char CameraParameters::ANTIBANDING_OFF[] = "off";
+
+// Values for flash mode settings.
+const char CameraParameters::FLASH_MODE_OFF[] = "off";
+const char CameraParameters::FLASH_MODE_AUTO[] = "auto";
+const char CameraParameters::FLASH_MODE_ON[] = "on";
+const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye";
+const char CameraParameters::FLASH_MODE_TORCH[] = "torch";
+
+// Values for scene mode settings.
+const char CameraParameters::SCENE_MODE_AUTO[] = "auto";
+const char CameraParameters::SCENE_MODE_ACTION[] = "action";
+const char CameraParameters::SCENE_MODE_PORTRAIT[] = "portrait";
+const char CameraParameters::SCENE_MODE_LANDSCAPE[] = "landscape";
+const char CameraParameters::SCENE_MODE_NIGHT[] = "night";
+const char CameraParameters::SCENE_MODE_NIGHT_PORTRAIT[] = "night-portrait";
+const char CameraParameters::SCENE_MODE_THEATRE[] = "theatre";
+const char CameraParameters::SCENE_MODE_BEACH[] = "beach";
+const char CameraParameters::SCENE_MODE_SNOW[] = "snow";
+const char CameraParameters::SCENE_MODE_SUNSET[] = "sunset";
+const char CameraParameters::SCENE_MODE_STEADYPHOTO[] = "steadyphoto";
+const char CameraParameters::SCENE_MODE_FIREWORKS[] = "fireworks";
+const char CameraParameters::SCENE_MODE_SPORTS[] = "sports";
+const char CameraParameters::SCENE_MODE_PARTY[] = "party";
+const char CameraParameters::SCENE_MODE_CANDLELIGHT[] = "candlelight";
+const char CameraParameters::SCENE_MODE_BARCODE[] = "barcode";
+const char CameraParameters::SCENE_MODE_HDR[] = "hdr";
+
+const char CameraParameters::PIXEL_FORMAT_YUV422SP[] = "yuv422sp";
+const char CameraParameters::PIXEL_FORMAT_YUV420SP[] = "yuv420sp";
+const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv";
+const char CameraParameters::PIXEL_FORMAT_YUV420P[]  = "yuv420p";
+const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
+const char CameraParameters::PIXEL_FORMAT_RGBA8888[] = "rgba8888";
+const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
+const char CameraParameters::PIXEL_FORMAT_BAYER_RGGB[] = "bayer-rggb";
+const char CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE[] = "android-opaque";
+
+// Values for focus mode settings.
+const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
+const char CameraParameters::FOCUS_MODE_INFINITY[] = "infinity";
+const char CameraParameters::FOCUS_MODE_MACRO[] = "macro";
+const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed";
+const char CameraParameters::FOCUS_MODE_EDOF[] = "edof";
+const char CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO[] = "continuous-video";
+const char CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE[] = "continuous-picture";
+
+// Values for light fx settings
+const char CameraParameters::LIGHTFX_LOWLIGHT[] = "low-light";
+const char CameraParameters::LIGHTFX_HDR[] = "high-dynamic-range";
+
+CameraParameters::CameraParameters()
+                : mMap()
+{
+}
+
+CameraParameters::~CameraParameters()
+{
+}
+
+String8 CameraParameters::flatten() const
+{
+    String8 flattened("");
+    size_t size = mMap.size();
+
+    for (size_t i = 0; i < size; i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+
+        flattened += k;
+        flattened += "=";
+        flattened += v;
+        if (i != size-1)
+            flattened += ";";
+    }
+
+    return flattened;
+}
+
+void CameraParameters::unflatten(const String8 &params)
+{
+    const char *a = params.string();
+    const char *b;
+
+    mMap.clear();
+
+    for (;;) {
+        // Find the bounds of the key name.
+        b = strchr(a, '=');
+        if (b == 0)
+            break;
+
+        // Create the key string.
+        String8 k(a, (size_t)(b-a));
+
+        // Find the value.
+        a = b+1;
+        b = strchr(a, ';');
+        if (b == 0) {
+            // If there's no semicolon, this is the last item.
+            String8 v(a);
+            mMap.add(k, v);
+            break;
+        }
+
+        String8 v(a, (size_t)(b-a));
+        mMap.add(k, v);
+        a = b+1;
+    }
+}
+
+
+void CameraParameters::set(const char *key, const char *value)
+{
+    // i think i can do this with strspn()
+    if (strchr(key, '=') || strchr(key, ';')) {
+        // ALOGE("Key \"%s\"contains invalid character (= or ;)", key);
+        return;
+    }
+
+    if (strchr(value, '=') || strchr(value, ';')) {
+        // ALOGE("Value \"%s\"contains invalid character (= or ;)", value);
+        return;
+    }
+
+    mMap.replaceValueFor(String8(key), String8(value));
+}
+
+void CameraParameters::set(const char *key, int value)
+{
+    char str[16];
+    sprintf(str, "%d", value);
+    set(key, str);
+}
+
+void CameraParameters::setFloat(const char *key, float value)
+{
+    char str[16];  // 14 should be enough. We overestimate to be safe.
+    snprintf(str, sizeof(str), "%g", value);
+    set(key, str);
+}
+
+const char *CameraParameters::get(const char *key) const
+{
+    String8 v = mMap.valueFor(String8(key));
+    if (v.length() == 0)
+        return 0;
+    return v.string();
+}
+
+int CameraParameters::getInt(const char *key) const
+{
+    const char *v = get(key);
+    if (v == 0)
+        return -1;
+    return strtol(v, 0, 0);
+}
+
+float CameraParameters::getFloat(const char *key) const
+{
+    const char *v = get(key);
+    if (v == 0) return -1;
+    return strtof(v, 0);
+}
+
+void CameraParameters::remove(const char *key)
+{
+    mMap.removeItem(String8(key));
+}
+
+// Parse string like "640x480" or "10000,20000"
+static int parse_pair(const char *str, int *first, int *second, char delim,
+                      char **endptr = NULL)
+{
+    // Find the first integer.
+    char *end;
+    int w = (int)strtol(str, &end, 10);
+    // If a delimeter does not immediately follow, give up.
+    if (*end != delim) {
+        ALOGE("Cannot find delimeter (%c) in str=%s", delim, str);
+        return -1;
+    }
+
+    // Find the second integer, immediately after the delimeter.
+    int h = (int)strtol(end+1, &end, 10);
+
+    *first = w;
+    *second = h;
+
+    if (endptr) {
+        *endptr = end;
+    }
+
+    return 0;
+}
+
+static void parseSizesList(const char *sizesStr, Vector<Size> &sizes)
+{
+    if (sizesStr == 0) {
+        return;
+    }
+
+    char *sizeStartPtr = (char *)sizesStr;
+
+    while (true) {
+        int width, height;
+        int success = parse_pair(sizeStartPtr, &width, &height, 'x',
+                                 &sizeStartPtr);
+        if (success == -1 || (*sizeStartPtr != ',' && *sizeStartPtr != '\0')) {
+            ALOGE("Picture sizes string \"%s\" contains invalid character.", sizesStr);
+            return;
+        }
+        sizes.push(Size(width, height));
+
+        if (*sizeStartPtr == '\0') {
+            return;
+        }
+        sizeStartPtr++;
+    }
+}
+
+void CameraParameters::setPreviewSize(int width, int height)
+{
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set(KEY_PREVIEW_SIZE, str);
+}
+
+void CameraParameters::getPreviewSize(int *width, int *height) const
+{
+    *width = *height = -1;
+    // Get the current string, if it doesn't exist, leave the -1x-1
+    const char *p = get(KEY_PREVIEW_SIZE);
+    if (p == 0)  return;
+    parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getPreferredPreviewSizeForVideo(int *width, int *height) const
+{
+    *width = *height = -1;
+    const char *p = get(KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO);
+    if (p == 0)  return;
+    parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getSupportedPreviewSizes(Vector<Size> &sizes) const
+{
+    const char *previewSizesStr = get(KEY_SUPPORTED_PREVIEW_SIZES);
+    parseSizesList(previewSizesStr, sizes);
+}
+
+void CameraParameters::setVideoSize(int width, int height)
+{
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set(KEY_VIDEO_SIZE, str);
+}
+
+void CameraParameters::getVideoSize(int *width, int *height) const
+{
+    *width = *height = -1;
+    const char *p = get(KEY_VIDEO_SIZE);
+    if (p == 0) return;
+    parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getSupportedVideoSizes(Vector<Size> &sizes) const
+{
+    const char *videoSizesStr = get(KEY_SUPPORTED_VIDEO_SIZES);
+    parseSizesList(videoSizesStr, sizes);
+}
+
+void CameraParameters::setPreviewFrameRate(int fps)
+{
+    set(KEY_PREVIEW_FRAME_RATE, fps);
+}
+
+int CameraParameters::getPreviewFrameRate() const
+{
+    return getInt(KEY_PREVIEW_FRAME_RATE);
+}
+
+void CameraParameters::getPreviewFpsRange(int *min_fps, int *max_fps) const
+{
+    *min_fps = *max_fps = -1;
+    const char *p = get(KEY_PREVIEW_FPS_RANGE);
+    if (p == 0) return;
+    parse_pair(p, min_fps, max_fps, ',');
+}
+
+void CameraParameters::setPreviewFormat(const char *format)
+{
+    set(KEY_PREVIEW_FORMAT, format);
+}
+
+const char *CameraParameters::getPreviewFormat() const
+{
+    return get(KEY_PREVIEW_FORMAT);
+}
+
+void CameraParameters::setPictureSize(int width, int height)
+{
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set(KEY_PICTURE_SIZE, str);
+}
+
+void CameraParameters::getPictureSize(int *width, int *height) const
+{
+    *width = *height = -1;
+    // Get the current string, if it doesn't exist, leave the -1x-1
+    const char *p = get(KEY_PICTURE_SIZE);
+    if (p == 0) return;
+    parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getSupportedPictureSizes(Vector<Size> &sizes) const
+{
+    const char *pictureSizesStr = get(KEY_SUPPORTED_PICTURE_SIZES);
+    parseSizesList(pictureSizesStr, sizes);
+}
+
+void CameraParameters::setPictureFormat(const char *format)
+{
+    set(KEY_PICTURE_FORMAT, format);
+}
+
+const char *CameraParameters::getPictureFormat() const
+{
+    return get(KEY_PICTURE_FORMAT);
+}
+
+void CameraParameters::dump() const
+{
+    ALOGD("dump: mMap.size = %zu", mMap.size());
+    for (size_t i = 0; i < mMap.size(); i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+        ALOGD("%s: %s\n", k.string(), v.string());
+    }
+}
+
+status_t CameraParameters::dump(int fd, const Vector<String16>& /*args*/) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %zu\n", mMap.size());
+    result.append(buffer);
+    for (size_t i = 0; i < mMap.size(); i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+        snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+void CameraParameters::getSupportedPreviewFormats(Vector<int>& formats) const {
+    const char* supportedPreviewFormats =
+          get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
+
+    if (supportedPreviewFormats == NULL) {
+        ALOGW("%s: No supported preview formats.", __FUNCTION__);
+        return;
+    }
+
+    String8 fmtStr(supportedPreviewFormats);
+    char* prevFmts = fmtStr.lockBuffer(fmtStr.size());
+
+    char* savePtr;
+    char* fmt = strtok_r(prevFmts, ",", &savePtr);
+    while (fmt) {
+        int actual = previewFormatToEnum(fmt);
+        if (actual != -1) {
+            formats.add(actual);
+        }
+        fmt = strtok_r(NULL, ",", &savePtr);
+    }
+    fmtStr.unlockBuffer(fmtStr.size());
+}
+
+
+int CameraParameters::previewFormatToEnum(const char* format) {
+    return
+        !format ?
+            HAL_PIXEL_FORMAT_YCrCb_420_SP :
+        !strcmp(format, PIXEL_FORMAT_YUV422SP) ?
+            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
+        !strcmp(format, PIXEL_FORMAT_YUV420SP) ?
+            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
+        !strcmp(format, PIXEL_FORMAT_YUV422I) ?
+            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
+        !strcmp(format, PIXEL_FORMAT_YUV420P) ?
+            HAL_PIXEL_FORMAT_YV12 :         // YV12
+        !strcmp(format, PIXEL_FORMAT_RGB565) ?
+            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
+        !strcmp(format, PIXEL_FORMAT_RGBA8888) ?
+            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
+        !strcmp(format, PIXEL_FORMAT_BAYER_RGGB) ?
+            HAL_PIXEL_FORMAT_RAW16 :   // Raw sensor data
+        -1;
+}
+
+bool CameraParameters::isEmpty() const {
+    return mMap.isEmpty();
+}
+
+}; // namespace android
diff --git a/camera/provider/2.4/vts/functional/CameraParameters.h b/camera/provider/2.4/vts/functional/CameraParameters.h
new file mode 100644
index 0000000..ba33ffe
--- /dev/null
+++ b/camera/provider/2.4/vts/functional/CameraParameters.h
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2008 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_CAMERA_PARAMETERS_H
+#define ANDROID_HARDWARE_CAMERA_PARAMETERS_H
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+
+struct Size {
+    int width;
+    int height;
+
+    Size() {
+        width = 0;
+        height = 0;
+    }
+
+    Size(int w, int h) {
+        width = w;
+        height = h;
+    }
+};
+
+class CameraParameters
+{
+public:
+    CameraParameters();
+    CameraParameters(const String8 &params) { unflatten(params); }
+    ~CameraParameters();
+
+    String8 flatten() const;
+    void unflatten(const String8 &params);
+
+    void set(const char *key, const char *value);
+    void set(const char *key, int value);
+    void setFloat(const char *key, float value);
+    const char *get(const char *key) const;
+    int getInt(const char *key) const;
+    float getFloat(const char *key) const;
+
+    void remove(const char *key);
+
+    void setPreviewSize(int width, int height);
+    void getPreviewSize(int *width, int *height) const;
+    void getSupportedPreviewSizes(Vector<Size> &sizes) const;
+
+    // Set the dimensions in pixels to the given width and height
+    // for video frames. The given width and height must be one
+    // of the supported dimensions returned from
+    // getSupportedVideoSizes(). Must not be called if
+    // getSupportedVideoSizes() returns an empty Vector of Size.
+    void setVideoSize(int width, int height);
+    // Retrieve the current dimensions (width and height)
+    // in pixels for video frames, which must be one of the
+    // supported dimensions returned from getSupportedVideoSizes().
+    // Must not be called if getSupportedVideoSizes() returns an
+    // empty Vector of Size.
+    void getVideoSize(int *width, int *height) const;
+    // Retrieve a Vector of supported dimensions (width and height)
+    // in pixels for video frames. If sizes returned from the method
+    // is empty, the camera does not support calls to setVideoSize()
+    // or getVideoSize(). In adddition, it also indicates that
+    // the camera only has a single output, and does not have
+    // separate output for video frames and preview frame.
+    void getSupportedVideoSizes(Vector<Size> &sizes) const;
+    // Retrieve the preferred preview size (width and height) in pixels
+    // for video recording. The given width and height must be one of
+    // supported preview sizes returned from getSupportedPreviewSizes().
+    // Must not be called if getSupportedVideoSizes() returns an empty
+    // Vector of Size. If getSupportedVideoSizes() returns an empty
+    // Vector of Size, the width and height returned from this method
+    // is invalid, and is "-1x-1".
+    void getPreferredPreviewSizeForVideo(int *width, int *height) const;
+
+    void setPreviewFrameRate(int fps);
+    int getPreviewFrameRate() const;
+    void getPreviewFpsRange(int *min_fps, int *max_fps) const;
+    void setPreviewFormat(const char *format);
+    const char *getPreviewFormat() const;
+    void setPictureSize(int width, int height);
+    void getPictureSize(int *width, int *height) const;
+    void getSupportedPictureSizes(Vector<Size> &sizes) const;
+    void setPictureFormat(const char *format);
+    const char *getPictureFormat() const;
+
+    void dump() const;
+    status_t dump(int fd, const Vector<String16>& args) const;
+
+    /**
+     * Returns a Vector containing the supported preview formats
+     * as enums given in graphics.h.
+     */
+    void getSupportedPreviewFormats(Vector<int>& formats) const;
+
+    // Returns true if no keys are present
+    bool isEmpty() const;
+
+    // Parameter keys to communicate between camera application and driver.
+    // The access (read/write, read only, or write only) is viewed from the
+    // perspective of applications, not driver.
+
+    // Preview frame size in pixels (width x height).
+    // Example value: "480x320". Read/Write.
+    static const char KEY_PREVIEW_SIZE[];
+    // Supported preview frame sizes in pixels.
+    // Example value: "800x600,480x320". Read only.
+    static const char KEY_SUPPORTED_PREVIEW_SIZES[];
+    // The current minimum and maximum preview fps. This controls the rate of
+    // preview frames received (CAMERA_MSG_PREVIEW_FRAME). The minimum and
+    // maximum fps must be one of the elements from
+    // KEY_SUPPORTED_PREVIEW_FPS_RANGE parameter.
+    // Example value: "10500,26623"
+    static const char KEY_PREVIEW_FPS_RANGE[];
+    // The supported preview fps (frame-per-second) ranges. Each range contains
+    // a minimum fps and maximum fps. If minimum fps equals to maximum fps, the
+    // camera outputs frames in fixed frame rate. If not, the camera outputs
+    // frames in auto frame rate. The actual frame rate fluctuates between the
+    // minimum and the maximum. The list has at least one element. The list is
+    // sorted from small to large (first by maximum fps and then minimum fps).
+    // Example value: "(10500,26623),(15000,26623),(30000,30000)"
+    static const char KEY_SUPPORTED_PREVIEW_FPS_RANGE[];
+    // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in
+    // frameworks/av/include/camera/Camera.h. The default is
+    // PIXEL_FORMAT_YUV420SP. Example value: "yuv420sp" or PIXEL_FORMAT_XXX
+    // constants. Read/write.
+    static const char KEY_PREVIEW_FORMAT[];
+    // Supported image formats for preview frames.
+    // Example value: "yuv420sp,yuv422i-yuyv". Read only.
+    static const char KEY_SUPPORTED_PREVIEW_FORMATS[];
+    // Number of preview frames per second. This is the target frame rate. The
+    // actual frame rate depends on the driver.
+    // Example value: "15". Read/write.
+    static const char KEY_PREVIEW_FRAME_RATE[];
+    // Supported number of preview frames per second.
+    // Example value: "24,15,10". Read.
+    static const char KEY_SUPPORTED_PREVIEW_FRAME_RATES[];
+    // The dimensions for captured pictures in pixels (width x height).
+    // Example value: "1024x768". Read/write.
+    static const char KEY_PICTURE_SIZE[];
+    // Supported dimensions for captured pictures in pixels.
+    // Example value: "2048x1536,1024x768". Read only.
+    static const char KEY_SUPPORTED_PICTURE_SIZES[];
+    // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE
+    // in frameworks/base/include/camera/Camera.h.
+    // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write.
+    static const char KEY_PICTURE_FORMAT[];
+    // Supported image formats for captured pictures.
+    // Example value: "jpeg,rgb565". Read only.
+    static const char KEY_SUPPORTED_PICTURE_FORMATS[];
+    // The width (in pixels) of EXIF thumbnail in Jpeg picture.
+    // Example value: "512". Read/write.
+    static const char KEY_JPEG_THUMBNAIL_WIDTH[];
+    // The height (in pixels) of EXIF thumbnail in Jpeg picture.
+    // Example value: "384". Read/write.
+    static const char KEY_JPEG_THUMBNAIL_HEIGHT[];
+    // Supported EXIF thumbnail sizes (width x height). 0x0 means not thumbnail
+    // in EXIF.
+    // Example value: "512x384,320x240,0x0". Read only.
+    static const char KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[];
+    // The quality of the EXIF thumbnail in Jpeg picture. The range is 1 to 100,
+    // with 100 being the best.
+    // Example value: "90". Read/write.
+    static const char KEY_JPEG_THUMBNAIL_QUALITY[];
+    // Jpeg quality of captured picture. The range is 1 to 100, with 100 being
+    // the best.
+    // Example value: "90". Read/write.
+    static const char KEY_JPEG_QUALITY[];
+    // The rotation angle in degrees relative to the orientation of the camera.
+    // This affects the pictures returned from CAMERA_MSG_COMPRESSED_IMAGE. The
+    // camera driver may set orientation in the EXIF header without rotating the
+    // picture. Or the driver may rotate the picture and the EXIF thumbnail. If
+    // the Jpeg picture is rotated, the orientation in the EXIF header will be
+    // missing or 1 (row #0 is top and column #0 is left side).
+    //
+    // Note that the JPEG pictures of front-facing cameras are not mirrored
+    // as in preview display.
+    //
+    // For example, suppose the natural orientation of the device is portrait.
+    // The device is rotated 270 degrees clockwise, so the device orientation is
+    // 270. Suppose a back-facing camera sensor is mounted in landscape and the
+    // top side of the camera sensor is aligned with the right edge of the
+    // display in natural orientation. So the camera orientation is 90. The
+    // rotation should be set to 0 (270 + 90).
+    //
+    // Example value: "0" or "90" or "180" or "270". Write only.
+    static const char KEY_ROTATION[];
+    // GPS latitude coordinate. GPSLatitude and GPSLatitudeRef will be stored in
+    // JPEG EXIF header.
+    // Example value: "25.032146" or "-33.462809". Write only.
+    static const char KEY_GPS_LATITUDE[];
+    // GPS longitude coordinate. GPSLongitude and GPSLongitudeRef will be stored
+    // in JPEG EXIF header.
+    // Example value: "121.564448" or "-70.660286". Write only.
+    static const char KEY_GPS_LONGITUDE[];
+    // GPS altitude. GPSAltitude and GPSAltitudeRef will be stored in JPEG EXIF
+    // header.
+    // Example value: "21.0" or "-5". Write only.
+    static const char KEY_GPS_ALTITUDE[];
+    // GPS timestamp (UTC in seconds since January 1, 1970). This should be
+    // stored in JPEG EXIF header.
+    // Example value: "1251192757". Write only.
+    static const char KEY_GPS_TIMESTAMP[];
+    // GPS Processing Method
+    // Example value: "GPS" or "NETWORK". Write only.
+    static const char KEY_GPS_PROCESSING_METHOD[];
+    // Current white balance setting.
+    // Example value: "auto" or WHITE_BALANCE_XXX constants. Read/write.
+    static const char KEY_WHITE_BALANCE[];
+    // Supported white balance settings.
+    // Example value: "auto,incandescent,daylight". Read only.
+    static const char KEY_SUPPORTED_WHITE_BALANCE[];
+    // Current color effect setting.
+    // Example value: "none" or EFFECT_XXX constants. Read/write.
+    static const char KEY_EFFECT[];
+    // Supported color effect settings.
+    // Example value: "none,mono,sepia". Read only.
+    static const char KEY_SUPPORTED_EFFECTS[];
+    // Current antibanding setting.
+    // Example value: "auto" or ANTIBANDING_XXX constants. Read/write.
+    static const char KEY_ANTIBANDING[];
+    // Supported antibanding settings.
+    // Example value: "auto,50hz,60hz,off". Read only.
+    static const char KEY_SUPPORTED_ANTIBANDING[];
+    // Current scene mode.
+    // Example value: "auto" or SCENE_MODE_XXX constants. Read/write.
+    static const char KEY_SCENE_MODE[];
+    // Supported scene mode settings.
+    // Example value: "auto,night,fireworks". Read only.
+    static const char KEY_SUPPORTED_SCENE_MODES[];
+    // Current flash mode.
+    // Example value: "auto" or FLASH_MODE_XXX constants. Read/write.
+    static const char KEY_FLASH_MODE[];
+    // Supported flash modes.
+    // Example value: "auto,on,off". Read only.
+    static const char KEY_SUPPORTED_FLASH_MODES[];
+    // Current focus mode. This will not be empty. Applications should call
+    // CameraHardwareInterface.autoFocus to start the focus if focus mode is
+    // FOCUS_MODE_AUTO or FOCUS_MODE_MACRO.
+    // Example value: "auto" or FOCUS_MODE_XXX constants. Read/write.
+    static const char KEY_FOCUS_MODE[];
+    // Supported focus modes.
+    // Example value: "auto,macro,fixed". Read only.
+    static const char KEY_SUPPORTED_FOCUS_MODES[];
+    // The maximum number of focus areas supported. This is the maximum length
+    // of KEY_FOCUS_AREAS.
+    // Example value: "0" or "2". Read only.
+    static const char KEY_MAX_NUM_FOCUS_AREAS[];
+    // Current focus areas.
+    //
+    // Before accessing this parameter, apps should check
+    // KEY_MAX_NUM_FOCUS_AREAS first to know the maximum number of focus areas
+    // first. If the value is 0, focus area is not supported.
+    //
+    // Each focus area is a five-element int array. The first four elements are
+    // the rectangle of the area (left, top, right, bottom). The direction is
+    // relative to the sensor orientation, that is, what the sensor sees. The
+    // direction is not affected by the rotation or mirroring of
+    // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates range from -1000 to 1000.
+    // (-1000,-1000) is the upper left point. (1000, 1000) is the lower right
+    // point. The width and height of focus areas cannot be 0 or negative.
+    //
+    // The fifth element is the weight. Values for weight must range from 1 to
+    // 1000.  The weight should be interpreted as a per-pixel weight - all
+    // pixels in the area have the specified weight. This means a small area
+    // with the same weight as a larger area will have less influence on the
+    // focusing than the larger area. Focus areas can partially overlap and the
+    // driver will add the weights in the overlap region.
+    //
+    // A special case of single focus area (0,0,0,0,0) means driver to decide
+    // the focus area. For example, the driver may use more signals to decide
+    // focus areas and change them dynamically. Apps can set (0,0,0,0,0) if they
+    // want the driver to decide focus areas.
+    //
+    // Focus areas are relative to the current field of view (KEY_ZOOM). No
+    // matter what the zoom level is, (-1000,-1000) represents the top of the
+    // currently visible camera frame. The focus area cannot be set to be
+    // outside the current field of view, even when using zoom.
+    //
+    // Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO,
+    // FOCUS_MODE_MACRO, FOCUS_MODE_CONTINUOUS_VIDEO, or
+    // FOCUS_MODE_CONTINUOUS_PICTURE.
+    // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
+    static const char KEY_FOCUS_AREAS[];
+    // Focal length in millimeter.
+    // Example value: "4.31". Read only.
+    static const char KEY_FOCAL_LENGTH[];
+    // Horizontal angle of view in degrees.
+    // Example value: "54.8". Read only.
+    static const char KEY_HORIZONTAL_VIEW_ANGLE[];
+    // Vertical angle of view in degrees.
+    // Example value: "42.5". Read only.
+    static const char KEY_VERTICAL_VIEW_ANGLE[];
+    // Exposure compensation index. 0 means exposure is not adjusted.
+    // Example value: "-5" or "5". Read/write.
+    static const char KEY_EXPOSURE_COMPENSATION[];
+    // The maximum exposure compensation index (>=0).
+    // Example value: "6". Read only.
+    static const char KEY_MAX_EXPOSURE_COMPENSATION[];
+    // The minimum exposure compensation index (<=0).
+    // Example value: "-6". Read only.
+    static const char KEY_MIN_EXPOSURE_COMPENSATION[];
+    // The exposure compensation step. Exposure compensation index multiply by
+    // step eqals to EV. Ex: if exposure compensation index is -6 and step is
+    // 0.3333, EV is -2.
+    // Example value: "0.333333333" or "0.5". Read only.
+    static const char KEY_EXPOSURE_COMPENSATION_STEP[];
+    // The state of the auto-exposure lock. "true" means that
+    // auto-exposure is locked to its current value and will not
+    // change. "false" means the auto-exposure routine is free to
+    // change exposure values. If auto-exposure is already locked,
+    // setting this to true again has no effect (the driver will not
+    // recalculate exposure values). Changing exposure compensation
+    // settings will still affect the exposure settings while
+    // auto-exposure is locked. Stopping preview or taking a still
+    // image will not change the lock. In conjunction with
+    // exposure compensation, this allows for capturing multi-exposure
+    // brackets with known relative exposure values. Locking
+    // auto-exposure after open but before the first call to
+    // startPreview may result in severely over- or under-exposed
+    // images.  The driver will not change the AE lock after
+    // auto-focus completes.
+    static const char KEY_AUTO_EXPOSURE_LOCK[];
+    // Whether locking the auto-exposure is supported. "true" means it is, and
+    // "false" or this key not existing means it is not supported.
+    static const char KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[];
+    // The state of the auto-white balance lock. "true" means that
+    // auto-white balance is locked to its current value and will not
+    // change. "false" means the auto-white balance routine is free to
+    // change white balance values. If auto-white balance is already
+    // locked, setting this to true again has no effect (the driver
+    // will not recalculate white balance values). Stopping preview or
+    // taking a still image will not change the lock. In conjunction
+    // with exposure compensation, this allows for capturing
+    // multi-exposure brackets with fixed white balance. Locking
+    // auto-white balance after open but before the first call to
+    // startPreview may result in severely incorrect color.  The
+    // driver will not change the AWB lock after auto-focus
+    // completes.
+    static const char KEY_AUTO_WHITEBALANCE_LOCK[];
+    // Whether locking the auto-white balance is supported. "true"
+    // means it is, and "false" or this key not existing means it is
+    // not supported.
+    static const char KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[];
+
+    // The maximum number of metering areas supported. This is the maximum
+    // length of KEY_METERING_AREAS.
+    // Example value: "0" or "2". Read only.
+    static const char KEY_MAX_NUM_METERING_AREAS[];
+    // Current metering areas. Camera driver uses these areas to decide
+    // exposure.
+    //
+    // Before accessing this parameter, apps should check
+    // KEY_MAX_NUM_METERING_AREAS first to know the maximum number of metering
+    // areas first. If the value is 0, metering area is not supported.
+    //
+    // Each metering area is a rectangle with specified weight. The direction is
+    // relative to the sensor orientation, that is, what the sensor sees. The
+    // direction is not affected by the rotation or mirroring of
+    // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates of the rectangle range
+    // from -1000 to 1000. (-1000, -1000) is the upper left point. (1000, 1000)
+    // is the lower right point. The width and height of metering areas cannot
+    // be 0 or negative.
+    //
+    // The fifth element is the weight. Values for weight must range from 1 to
+    // 1000.  The weight should be interpreted as a per-pixel weight - all
+    // pixels in the area have the specified weight. This means a small area
+    // with the same weight as a larger area will have less influence on the
+    // metering than the larger area. Metering areas can partially overlap and
+    // the driver will add the weights in the overlap region.
+    //
+    // A special case of all-zero single metering area means driver to decide
+    // the metering area. For example, the driver may use more signals to decide
+    // metering areas and change them dynamically. Apps can set all-zero if they
+    // want the driver to decide metering areas.
+    //
+    // Metering areas are relative to the current field of view (KEY_ZOOM).
+    // No matter what the zoom level is, (-1000,-1000) represents the top of the
+    // currently visible camera frame. The metering area cannot be set to be
+    // outside the current field of view, even when using zoom.
+    //
+    // No matter what metering areas are, the final exposure are compensated
+    // by KEY_EXPOSURE_COMPENSATION.
+    // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
+    static const char KEY_METERING_AREAS[];
+    // Current zoom value.
+    // Example value: "0" or "6". Read/write.
+    static const char KEY_ZOOM[];
+    // Maximum zoom value.
+    // Example value: "6". Read only.
+    static const char KEY_MAX_ZOOM[];
+    // The zoom ratios of all zoom values. The zoom ratio is in 1/100
+    // increments. Ex: a zoom of 3.2x is returned as 320. The number of list
+    // elements is KEY_MAX_ZOOM + 1. The first element is always 100. The last
+    // element is the zoom ratio of zoom value KEY_MAX_ZOOM.
+    // Example value: "100,150,200,250,300,350,400". Read only.
+    static const char KEY_ZOOM_RATIOS[];
+    // Whether zoom is supported. Zoom is supported if the value is "true". Zoom
+    // is not supported if the value is not "true" or the key does not exist.
+    // Example value: "true". Read only.
+    static const char KEY_ZOOM_SUPPORTED[];
+    // Whether if smooth zoom is supported. Smooth zoom is supported if the
+    // value is "true". It is not supported if the value is not "true" or the
+    // key does not exist.
+    // See CAMERA_CMD_START_SMOOTH_ZOOM, CAMERA_CMD_STOP_SMOOTH_ZOOM, and
+    // CAMERA_MSG_ZOOM in frameworks/base/include/camera/Camera.h.
+    // Example value: "true". Read only.
+    static const char KEY_SMOOTH_ZOOM_SUPPORTED[];
+
+    // The distances (in meters) from the camera to where an object appears to
+    // be in focus. The object is sharpest at the optimal focus distance. The
+    // depth of field is the far focus distance minus near focus distance.
+    //
+    // Focus distances may change after starting auto focus, canceling auto
+    // focus, or starting the preview. Applications can read this anytime to get
+    // the latest focus distances. If the focus mode is FOCUS_MODE_CONTINUOUS,
+    // focus distances may change from time to time.
+    //
+    // This is intended to estimate the distance between the camera and the
+    // subject. After autofocus, the subject distance may be within near and far
+    // focus distance. However, the precision depends on the camera hardware,
+    // autofocus algorithm, the focus area, and the scene. The error can be
+    // large and it should be only used as a reference.
+    //
+    // Far focus distance > optimal focus distance > near focus distance. If
+    // the far focus distance is infinity, the value should be "Infinity" (case
+    // sensitive). The format is three float values separated by commas. The
+    // first is near focus distance. The second is optimal focus distance. The
+    // third is far focus distance.
+    // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only.
+    static const char KEY_FOCUS_DISTANCES[];
+
+    // The current dimensions in pixels (width x height) for video frames.
+    // The width and height must be one of the supported sizes retrieved
+    // via KEY_SUPPORTED_VIDEO_SIZES.
+    // Example value: "1280x720". Read/write.
+    static const char KEY_VIDEO_SIZE[];
+    // A list of the supported dimensions in pixels (width x height)
+    // for video frames. See CAMERA_MSG_VIDEO_FRAME for details in
+    // frameworks/base/include/camera/Camera.h.
+    // Example: "176x144,1280x720". Read only.
+    static const char KEY_SUPPORTED_VIDEO_SIZES[];
+
+    // The maximum number of detected faces supported by hardware face
+    // detection. If the value is 0, hardware face detection is not supported.
+    // Example: "5". Read only
+    static const char KEY_MAX_NUM_DETECTED_FACES_HW[];
+
+    // The maximum number of detected faces supported by software face
+    // detection. If the value is 0, software face detection is not supported.
+    // Example: "5". Read only
+    static const char KEY_MAX_NUM_DETECTED_FACES_SW[];
+
+    // Preferred preview frame size in pixels for video recording.
+    // The width and height must be one of the supported sizes retrieved
+    // via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when
+    // getSupportedVideoSizes() does not return an empty Vector of Size.
+    // Camcorder applications are recommended to set the preview size
+    // to a value that is not larger than the preferred preview size.
+    // In other words, the product of the width and height of the
+    // preview size should not be larger than that of the preferred
+    // preview size. In addition, we recommend to choos a preview size
+    // that has the same aspect ratio as the resolution of video to be
+    // recorded.
+    // Example value: "800x600". Read only.
+    static const char KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[];
+
+    // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in
+    // frameworks/base/include/camera/Camera.h.
+    // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
+    static const char KEY_VIDEO_FRAME_FORMAT[];
+
+    // Sets the hint of the recording mode. If this is true, MediaRecorder.start
+    // may be faster or has less glitches. This should be called before starting
+    // the preview for the best result. But it is allowed to change the hint
+    // while the preview is active. The default value is false.
+    //
+    // The apps can still call Camera.takePicture when the hint is true. The
+    // apps can call MediaRecorder.start when the hint is false. But the
+    // performance may be worse.
+    // Example value: "true" or "false". Read/write.
+    static const char KEY_RECORDING_HINT[];
+
+    // Returns true if video snapshot is supported. That is, applications
+    // can call Camera.takePicture during recording. Applications do not need to
+    // call Camera.startPreview after taking a picture. The preview will be
+    // still active. Other than that, taking a picture during recording is
+    // identical to taking a picture normally. All settings and methods related
+    // to takePicture work identically. Ex: KEY_PICTURE_SIZE,
+    // KEY_SUPPORTED_PICTURE_SIZES, KEY_JPEG_QUALITY, KEY_ROTATION, and etc.
+    // The picture will have an EXIF header. FLASH_MODE_AUTO and FLASH_MODE_ON
+    // also still work, but the video will record the flash.
+    //
+    // Applications can set shutter callback as null to avoid the shutter
+    // sound. It is also recommended to set raw picture and post view callbacks
+    // to null to avoid the interrupt of preview display.
+    //
+    // Field-of-view of the recorded video may be different from that of the
+    // captured pictures.
+    // Example value: "true" or "false". Read only.
+    static const char KEY_VIDEO_SNAPSHOT_SUPPORTED[];
+
+    // The state of the video stabilization. If set to true, both the
+    // preview stream and the recorded video stream are stabilized by
+    // the camera. Only valid to set if KEY_VIDEO_STABILIZATION_SUPPORTED is
+    // set to true.
+    //
+    // The value of this key can be changed any time the camera is
+    // open. If preview or recording is active, it is acceptable for
+    // there to be a slight video glitch when video stabilization is
+    // toggled on and off.
+    //
+    // This only stabilizes video streams (between-frames stabilization), and
+    // has no effect on still image capture.
+    static const char KEY_VIDEO_STABILIZATION[];
+
+    // Returns true if video stabilization is supported. That is, applications
+    // can set KEY_VIDEO_STABILIZATION to true and have a stabilized preview
+    // stream and record stabilized videos.
+    static const char KEY_VIDEO_STABILIZATION_SUPPORTED[];
+
+    // Supported modes for special effects with light.
+    // Example values: "lowlight,hdr".
+    static const char KEY_LIGHTFX[];
+
+    // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
+    static const char TRUE[];
+    static const char FALSE[];
+
+    // Value for KEY_FOCUS_DISTANCES.
+    static const char FOCUS_DISTANCE_INFINITY[];
+
+    // Values for white balance settings.
+    static const char WHITE_BALANCE_AUTO[];
+    static const char WHITE_BALANCE_INCANDESCENT[];
+    static const char WHITE_BALANCE_FLUORESCENT[];
+    static const char WHITE_BALANCE_WARM_FLUORESCENT[];
+    static const char WHITE_BALANCE_DAYLIGHT[];
+    static const char WHITE_BALANCE_CLOUDY_DAYLIGHT[];
+    static const char WHITE_BALANCE_TWILIGHT[];
+    static const char WHITE_BALANCE_SHADE[];
+
+    // Values for effect settings.
+    static const char EFFECT_NONE[];
+    static const char EFFECT_MONO[];
+    static const char EFFECT_NEGATIVE[];
+    static const char EFFECT_SOLARIZE[];
+    static const char EFFECT_SEPIA[];
+    static const char EFFECT_POSTERIZE[];
+    static const char EFFECT_WHITEBOARD[];
+    static const char EFFECT_BLACKBOARD[];
+    static const char EFFECT_AQUA[];
+
+    // Values for antibanding settings.
+    static const char ANTIBANDING_AUTO[];
+    static const char ANTIBANDING_50HZ[];
+    static const char ANTIBANDING_60HZ[];
+    static const char ANTIBANDING_OFF[];
+
+    // Values for flash mode settings.
+    // Flash will not be fired.
+    static const char FLASH_MODE_OFF[];
+    // Flash will be fired automatically when required. The flash may be fired
+    // during preview, auto-focus, or snapshot depending on the driver.
+    static const char FLASH_MODE_AUTO[];
+    // Flash will always be fired during snapshot. The flash may also be
+    // fired during preview or auto-focus depending on the driver.
+    static const char FLASH_MODE_ON[];
+    // Flash will be fired in red-eye reduction mode.
+    static const char FLASH_MODE_RED_EYE[];
+    // Constant emission of light during preview, auto-focus and snapshot.
+    // This can also be used for video recording.
+    static const char FLASH_MODE_TORCH[];
+
+    // Values for scene mode settings.
+    static const char SCENE_MODE_AUTO[];
+    static const char SCENE_MODE_ACTION[];
+    static const char SCENE_MODE_PORTRAIT[];
+    static const char SCENE_MODE_LANDSCAPE[];
+    static const char SCENE_MODE_NIGHT[];
+    static const char SCENE_MODE_NIGHT_PORTRAIT[];
+    static const char SCENE_MODE_THEATRE[];
+    static const char SCENE_MODE_BEACH[];
+    static const char SCENE_MODE_SNOW[];
+    static const char SCENE_MODE_SUNSET[];
+    static const char SCENE_MODE_STEADYPHOTO[];
+    static const char SCENE_MODE_FIREWORKS[];
+    static const char SCENE_MODE_SPORTS[];
+    static const char SCENE_MODE_PARTY[];
+    static const char SCENE_MODE_CANDLELIGHT[];
+    // Applications are looking for a barcode. Camera driver will be optimized
+    // for barcode reading.
+    static const char SCENE_MODE_BARCODE[];
+    // A high-dynamic range mode. In this mode, the HAL module will use a
+    // capture strategy that extends the dynamic range of the captured
+    // image in some fashion. Only the final image is returned.
+    static const char SCENE_MODE_HDR[];
+
+    // Pixel color formats for KEY_PREVIEW_FORMAT, KEY_PICTURE_FORMAT,
+    // and KEY_VIDEO_FRAME_FORMAT
+    static const char PIXEL_FORMAT_YUV422SP[];
+    static const char PIXEL_FORMAT_YUV420SP[]; // NV21
+    static const char PIXEL_FORMAT_YUV422I[]; // YUY2
+    static const char PIXEL_FORMAT_YUV420P[]; // YV12
+    static const char PIXEL_FORMAT_RGB565[];
+    static const char PIXEL_FORMAT_RGBA8888[];
+    static const char PIXEL_FORMAT_JPEG[];
+    // Raw bayer format used for images, which is 10 bit precision samples
+    // stored in 16 bit words. The filter pattern is RGGB.
+    static const char PIXEL_FORMAT_BAYER_RGGB[];
+    // Pixel format is not known to the framework
+    static const char PIXEL_FORMAT_ANDROID_OPAQUE[];
+
+    // Values for focus mode settings.
+    // Auto-focus mode. Applications should call
+    // CameraHardwareInterface.autoFocus to start the focus in this mode.
+    static const char FOCUS_MODE_AUTO[];
+    // Focus is set at infinity. Applications should not call
+    // CameraHardwareInterface.autoFocus in this mode.
+    static const char FOCUS_MODE_INFINITY[];
+    // Macro (close-up) focus mode. Applications should call
+    // CameraHardwareInterface.autoFocus to start the focus in this mode.
+    static const char FOCUS_MODE_MACRO[];
+    // Focus is fixed. The camera is always in this mode if the focus is not
+    // adjustable. If the camera has auto-focus, this mode can fix the
+    // focus, which is usually at hyperfocal distance. Applications should
+    // not call CameraHardwareInterface.autoFocus in this mode.
+    static const char FOCUS_MODE_FIXED[];
+    // Extended depth of field (EDOF). Focusing is done digitally and
+    // continuously. Applications should not call
+    // CameraHardwareInterface.autoFocus in this mode.
+    static const char FOCUS_MODE_EDOF[];
+    // Continuous auto focus mode intended for video recording. The camera
+    // continuously tries to focus. This is the best choice for video
+    // recording because the focus changes smoothly . Applications still can
+    // call CameraHardwareInterface.takePicture in this mode but the subject may
+    // not be in focus. Auto focus starts when the parameter is set.
+    //
+    // Applications can call CameraHardwareInterface.autoFocus in this mode. The
+    // focus callback will immediately return with a boolean that indicates
+    // whether the focus is sharp or not. The focus position is locked after
+    // autoFocus call. If applications want to resume the continuous focus,
+    // cancelAutoFocus must be called. Restarting the preview will not resume
+    // the continuous autofocus. To stop continuous focus, applications should
+    // change the focus mode to other modes.
+    static const char FOCUS_MODE_CONTINUOUS_VIDEO[];
+    // Continuous auto focus mode intended for taking pictures. The camera
+    // continuously tries to focus. The speed of focus change is more aggressive
+    // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is
+    // set.
+    //
+    // Applications can call CameraHardwareInterface.autoFocus in this mode. If
+    // the autofocus is in the middle of scanning, the focus callback will
+    // return when it completes. If the autofocus is not scanning, focus
+    // callback will immediately return with a boolean that indicates whether
+    // the focus is sharp or not. The apps can then decide if they want to take
+    // a picture immediately or to change the focus mode to auto, and run a full
+    // autofocus cycle. The focus position is locked after autoFocus call. If
+    // applications want to resume the continuous focus, cancelAutoFocus must be
+    // called. Restarting the preview will not resume the continuous autofocus.
+    // To stop continuous focus, applications should change the focus mode to
+    // other modes.
+    static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
+
+    // Values for light special effects
+    // Low-light enhancement mode
+    static const char LIGHTFX_LOWLIGHT[];
+    // High-dynamic range mode
+    static const char LIGHTFX_HDR[];
+
+    /**
+     * Returns the the supported preview formats as an enum given in graphics.h
+     * corrsponding to the format given in the input string or -1 if no such
+     * conversion exists.
+     */
+    static int previewFormatToEnum(const char* format);
+
+private:
+    DefaultKeyedVector<String8,String8>    mMap;
+};
+
+}; // namespace android
+
+#endif
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index ce195f8..598127f 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -17,9 +17,16 @@
 #define LOG_TAG "camera_hidl_hal_test"
 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android/hardware/camera/device/1.0/ICameraDevice.h>
+#include "CameraParameters.h"
+#include <system/camera.h>
 #include <android/log.h>
 #include <ui/GraphicBuffer.h>
 #include <VtsHalHidlTargetTestBase.h>
+#include <gui/BufferQueue.h>
+#include <gui/Surface.h>
+#include <gui/BufferItemConsumer.h>
+#include <binder/MemoryHeapBase.h>
 #include <regex>
 #include "system/camera_metadata.h"
 #include <hardware/gralloc.h>
@@ -29,6 +36,7 @@
 #include <condition_variable>
 #include <chrono>
 #include <inttypes.h>
+#include <utils/Errors.h>
 
 using ::android::hardware::Return;
 using ::android::hardware::Void;
@@ -36,14 +44,23 @@
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::sp;
+using ::android::wp;
 using ::android::GraphicBuffer;
+using ::android::IGraphicBufferProducer;
+using ::android::IGraphicBufferConsumer;
+using ::android::BufferQueue;
+using ::android::BufferItemConsumer;
+using ::android::Surface;
+using ::android::CameraParameters;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
 using ::android::hardware::camera::common::V1_0::Status;
 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
 using ::android::hardware::camera::common::V1_0::TorchMode;
 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
+using ::android::hardware::camera::device::V3_2::ICameraDevice;
 using ::android::hardware::camera::device::V3_2::CaptureRequest;
 using ::android::hardware::camera::device::V3_2::CaptureResult;
 using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
@@ -59,14 +76,27 @@
 using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
 using ::android::hardware::camera::device::V3_2::BufferStatus;
 using ::android::hardware::camera::device::V3_2::StreamBuffer;
+using ::android::hardware::camera::device::V3_2::MsgType;
+using ::android::hardware::camera::device::V3_2::ErrorMsg;
+using ::android::hardware::camera::device::V3_2::ErrorCode;
+using ::android::hardware::camera::device::V1_0::CameraFacing;
+using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg;
+using ::android::hardware::camera::device::V1_0::CommandType;
+using ::android::hardware::camera::device::V1_0::DataCallbackMsg;
+using ::android::hardware::camera::device::V1_0::CameraFrameMetadata;
+using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
+using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
 
-#define CAMERA_PASSTHROUGH_SERVICE_NAME "legacy/0"
-#define MAX_PREVIEW_WIDTH  1920
-#define MAX_PREVIEW_HEIGHT 1080
-#define MAX_VIDEO_WIDTH    4096
-#define MAX_VIDEO_HEIGHT   2160
-#define STREAM_BUFFER_TIMEOUT 3  // sec.
-#define DUMP_OUTPUT "/dev/null"
+const char kCameraPassthroughServiceName[] = "legacy/0";
+const uint32_t kMaxPreviewWidth = 1920;
+const uint32_t kMaxPreviewHeight = 1080;
+const uint32_t kMaxVideoWidth = 4096;
+const uint32_t kMaxVideoHeight = 2160;
+const int64_t kStreamBufferTimeoutSec = 3;
+const int64_t kAutoFocusTimeoutSec = 5;
+const int64_t kTorchTimeoutSec = 1;
+const int64_t kEmptyFlushTimeoutMSec = 200;
+const char kDumpOutput[] = "/dev/null";
 
 struct AvailableStream {
     int32_t width;
@@ -99,14 +129,36 @@
         if (!match) {
             return -1;
         }
-        if (sm[1].compare(kHAL3_2) == 0) {
+        std::string version = sm[1].str();
+        if (version.compare(kHAL3_2) == 0) {
             // maybe switched to 3.4 or define the hidl version enumlater
             return CAMERA_DEVICE_API_VERSION_3_2;
-        } else if (sm[1].compare(kHAL1_0) == 0) {
+        } else if (version.compare(kHAL1_0) == 0) {
             return CAMERA_DEVICE_API_VERSION_1_0;
         }
         return 0;
     }
+
+    Status mapToStatus(::android::status_t s)  {
+        switch(s) {
+            case ::android::OK:
+                return Status::OK ;
+            case ::android::BAD_VALUE:
+                return Status::ILLEGAL_ARGUMENT ;
+            case -EBUSY:
+                return Status::CAMERA_IN_USE;
+            case -EUSERS:
+                return Status::MAX_CAMERAS_IN_USE;
+            case ::android::UNKNOWN_TRANSACTION:
+                return Status::METHOD_NOT_SUPPORTED;
+            case ::android::INVALID_OPERATION:
+                return Status::OPERATION_NOT_SUPPORTED;
+            case ::android::DEAD_OBJECT:
+                return Status::CAMERA_DISCONNECTED;
+        }
+        ALOGW("Unexpected HAL status code %d", s);
+        return Status::OPERATION_NOT_SUPPORTED;
+    }
 }
 
 // Test environment for camera
@@ -131,7 +183,7 @@
 
 void CameraHidlEnvironment::SetUp() {
     // TODO: test the binderized mode
-    mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(CAMERA_PASSTHROUGH_SERVICE_NAME);
+    mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(kCameraPassthroughServiceName);
     // TODO: handle the device doesn't have any camera case
     ALOGI_IF(mProvider, "provider is not nullptr, %p", mProvider.get());
     ASSERT_NE(mProvider, nullptr);
@@ -141,6 +193,249 @@
     ALOGI("TearDown CameraHidlEnvironment");
 }
 
+struct BufferItemHander: public BufferItemConsumer::FrameAvailableListener {
+    BufferItemHander(wp<BufferItemConsumer> consumer) : mConsumer(consumer) {}
+
+    void onFrameAvailable(const android::BufferItem&) override {
+        sp<BufferItemConsumer> consumer = mConsumer.promote();
+        ASSERT_NE(nullptr, consumer.get());
+
+        android::BufferItem buffer;
+        ASSERT_EQ(android::OK, consumer->acquireBuffer(&buffer, 0));
+        ASSERT_EQ(android::OK, consumer->releaseBuffer(buffer));
+    }
+
+ private:
+    wp<BufferItemConsumer> mConsumer;
+};
+
+struct PreviewWindowCb : public ICameraDevicePreviewCallback {
+    PreviewWindowCb(sp<ANativeWindow> anw) : mPreviewWidth(0),
+            mPreviewHeight(0), mFormat(0), mPreviewUsage(0),
+            mPreviewSwapInterval(-1), mCrop{-1, -1, -1, -1}, mAnw(anw) {}
+
+    using dequeueBuffer_cb =
+            std::function<void(Status status, uint64_t bufferId,
+                    const hidl_handle& buffer, uint32_t stride)>;
+    Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override;
+
+    Return<Status> enqueueBuffer(uint64_t bufferId) override;
+
+    Return<Status> cancelBuffer(uint64_t bufferId) override;
+
+    Return<Status> setBufferCount(uint32_t count) override;
+
+    Return<Status> setBuffersGeometry(uint32_t w,
+            uint32_t h, PixelFormat format) override;
+
+    Return<Status> setCrop(int32_t left, int32_t top,
+            int32_t right, int32_t bottom) override;
+
+    Return<Status> setUsage(ProducerUsage usage) override;
+
+    Return<Status> setSwapInterval(int32_t interval) override;
+
+    using getMinUndequeuedBufferCount_cb =
+            std::function<void(Status status, uint32_t count)>;
+    Return<void> getMinUndequeuedBufferCount(
+            getMinUndequeuedBufferCount_cb _hidl_cb) override;
+
+    Return<Status> setTimestamp(int64_t timestamp) override;
+
+ private:
+    struct BufferHasher {
+        size_t operator()(const buffer_handle_t& buf) const {
+            if (buf == nullptr)
+                return 0;
+
+            size_t result = 1;
+            result = 31 * result + buf->numFds;
+            result = 31 * result + buf->numInts;
+            int length = buf->numFds + buf->numInts;
+            for (int i = 0; i < length; i++) {
+                result = 31 * result + buf->data[i];
+            }
+            return result;
+        }
+    };
+
+    struct BufferComparator {
+        bool operator()(const buffer_handle_t& buf1,
+                const buffer_handle_t& buf2) const {
+            if ((buf1->numFds == buf2->numFds) &&
+                    (buf1->numInts == buf2->numInts)) {
+                int length = buf1->numFds + buf1->numInts;
+                for (int i = 0; i < length; i++) {
+                    if (buf1->data[i] != buf2->data[i]) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+    };
+
+    std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb);
+    void cleanupCirculatingBuffers();
+
+    std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId
+    typedef std::unordered_map<const buffer_handle_t, uint64_t,
+            BufferHasher, BufferComparator> BufferIdMap;
+
+    BufferIdMap mBufferIdMap; // stream ID -> per stream buffer ID map
+    std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap;
+    uint64_t mNextBufferId = 1;
+
+    uint32_t mPreviewWidth, mPreviewHeight;
+    int mFormat, mPreviewUsage;
+    int32_t mPreviewSwapInterval;
+    android_native_rect_t mCrop;
+    sp<ANativeWindow> mAnw;     //Native window reference
+};
+
+std::pair<bool, uint64_t> PreviewWindowCb::getBufferId(
+        ANativeWindowBuffer* anb) {
+    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
+
+    buffer_handle_t& buf = anb->handle;
+    auto it = mBufferIdMap.find(buf);
+    if (it == mBufferIdMap.end()) {
+        uint64_t bufId = mNextBufferId++;
+        mBufferIdMap[buf] = bufId;
+        mReversedBufMap[bufId] = anb;
+        return std::make_pair(true, bufId);
+    } else {
+        return std::make_pair(false, it->second);
+    }
+}
+
+void PreviewWindowCb::cleanupCirculatingBuffers() {
+    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
+    mBufferIdMap.clear();
+    mReversedBufMap.clear();
+}
+
+Return<void> PreviewWindowCb::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
+    ANativeWindowBuffer* anb;
+    auto rc = native_window_dequeue_buffer_and_wait(mAnw.get(), &anb);
+    uint64_t bufferId = 0;
+    uint32_t stride = 0;
+    hidl_handle buf = nullptr;
+    if (rc == ::android::OK) {
+        auto pair = getBufferId(anb);
+        buf = (pair.first) ? anb->handle : nullptr;
+        bufferId = pair.second;
+        stride = anb->stride;
+    }
+
+    _hidl_cb(mapToStatus(rc), bufferId, buf, stride);
+    return Void();
+}
+
+Return<Status> PreviewWindowCb::enqueueBuffer(uint64_t bufferId) {
+    if (mReversedBufMap.count(bufferId) == 0) {
+        ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+    return mapToStatus(mAnw->queueBuffer(mAnw.get(),
+            mReversedBufMap.at(bufferId), -1));
+}
+
+Return<Status> PreviewWindowCb::cancelBuffer(uint64_t bufferId) {
+    if (mReversedBufMap.count(bufferId) == 0) {
+        ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+    return mapToStatus(mAnw->cancelBuffer(mAnw.get(),
+            mReversedBufMap.at(bufferId), -1));
+}
+
+Return<Status> PreviewWindowCb::setBufferCount(uint32_t count) {
+    if (mAnw.get() != nullptr) {
+        // WAR for b/27039775
+        native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
+        native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
+        if (mPreviewWidth != 0) {
+            native_window_set_buffers_dimensions(mAnw.get(),
+                    mPreviewWidth, mPreviewHeight);
+            native_window_set_buffers_format(mAnw.get(), mFormat);
+        }
+        if (mPreviewUsage != 0) {
+            native_window_set_usage(mAnw.get(), mPreviewUsage);
+        }
+        if (mPreviewSwapInterval >= 0) {
+            mAnw->setSwapInterval(mAnw.get(), mPreviewSwapInterval);
+        }
+        if (mCrop.left >= 0) {
+            native_window_set_crop(mAnw.get(), &(mCrop));
+        }
+    }
+
+    auto rc = native_window_set_buffer_count(mAnw.get(), count);
+    if (rc == ::android::OK) {
+        cleanupCirculatingBuffers();
+    }
+
+    return mapToStatus(rc);
+}
+
+Return<Status> PreviewWindowCb::setBuffersGeometry(uint32_t w, uint32_t h,
+        PixelFormat format) {
+    auto rc = native_window_set_buffers_dimensions(mAnw.get(), w, h);
+    if (rc == ::android::OK) {
+        mPreviewWidth = w;
+        mPreviewHeight = h;
+        rc = native_window_set_buffers_format(mAnw.get(),
+                static_cast<int>(format));
+        if (rc == ::android::OK) {
+            mFormat = static_cast<int>(format);
+        }
+    }
+
+    return mapToStatus(rc);
+}
+
+Return<Status> PreviewWindowCb::setCrop(int32_t left, int32_t top,
+        int32_t right, int32_t bottom) {
+    android_native_rect_t crop = { left, top, right, bottom };
+    auto rc = native_window_set_crop(mAnw.get(), &crop);
+    if (rc == ::android::OK) {
+        mCrop = crop;
+    }
+    return mapToStatus(rc);
+}
+
+Return<Status> PreviewWindowCb::setUsage(ProducerUsage usage) {
+    auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
+    if (rc == ::android::OK) {
+        mPreviewUsage =  static_cast<int>(usage);
+    }
+    return mapToStatus(rc);
+}
+
+Return<Status> PreviewWindowCb::setSwapInterval(int32_t interval) {
+    auto rc = mAnw->setSwapInterval(mAnw.get(), interval);
+    if (rc == ::android::OK) {
+        mPreviewSwapInterval = interval;
+    }
+    return mapToStatus(rc);
+}
+
+Return<void> PreviewWindowCb::getMinUndequeuedBufferCount(
+        getMinUndequeuedBufferCount_cb _hidl_cb) {
+    int count = 0;
+    auto rc = mAnw->query(mAnw.get(),
+            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
+    _hidl_cb(mapToStatus(rc), count);
+    return Void();
+}
+
+Return<Status> PreviewWindowCb::setTimestamp(int64_t timestamp) {
+    return mapToStatus(native_window_set_buffers_timestamp(mAnw.get(),
+            timestamp));
+}
+
 // The main test class for camera HIDL HAL.
 class CameraHidlTest : public ::testing::VtsHalHidlTargetTestBase {
 public:
@@ -172,9 +467,88 @@
         CameraHidlTest *mParent;               // Parent object
     };
 
+    struct TorchProviderCb : public ICameraProviderCallback {
+        TorchProviderCb(CameraHidlTest *parent) : mParent(parent) {}
+        virtual Return<void> cameraDeviceStatusChange(
+                const hidl_string&, CameraDeviceStatus) override {
+            return Void();
+        }
+
+        virtual Return<void> torchModeStatusChange(
+                const hidl_string&, TorchModeStatus newStatus) override {
+            std::lock_guard<std::mutex> l(mParent->mTorchLock);
+            mParent->mTorchStatus = newStatus;
+            mParent->mTorchCond.notify_one();
+            return Void();
+        }
+
+     private:
+        CameraHidlTest *mParent;               // Parent object
+    };
+
+    struct Camera1DeviceCb :
+            public ::android::hardware::camera::device::V1_0::ICameraDeviceCallback {
+        Camera1DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
+
+        Return<void> notifyCallback(NotifyCallbackMsg msgType,
+                int32_t ext1, int32_t ext2) override;
+
+        Return<uint32_t> registerMemory(const hidl_handle& descriptor,
+                uint32_t bufferSize, uint32_t bufferCount) override;
+
+        Return<void> unregisterMemory(uint32_t memId) override;
+
+        Return<void> dataCallback(DataCallbackMsg msgType,
+                uint32_t data, uint32_t bufferIndex,
+                const CameraFrameMetadata& metadata) override;
+
+        Return<void> dataCallbackTimestamp(DataCallbackMsg msgType,
+                uint32_t data, uint32_t bufferIndex,
+                int64_t timestamp) override;
+
+        Return<void> handleCallbackTimestamp(DataCallbackMsg msgType,
+                const hidl_handle& frameData,uint32_t data,
+                uint32_t bufferIndex, int64_t timestamp) override;
+
+     private:
+        CameraHidlTest *mParent;               // Parent object
+    };
+
+    void openCameraDevice(const std::string &name,const CameraHidlEnvironment* env,
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
+    void setupPreviewWindow(
+            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
+            sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
+            sp<BufferItemHander> *bufferHandler /*out*/);
+    void stopPreviewAndClose(
+            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
+    void startPreview(
+            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
+    void enableMsgType(unsigned int msgType,
+            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
+    void disableMsgType(unsigned int msgType,
+            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
+    void getParameters(
+            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
+            CameraParameters *cameraParams /*out*/);
+    void setParameters(
+            const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
+            const CameraParameters &cameraParams);
+    void waitForFrameLocked(DataCallbackMsg msgFrame,
+            std::unique_lock<std::mutex> &l);
+    void openEmptyDeviceSession(const std::string &name,
+            const CameraHidlEnvironment* env,
+            sp<ICameraDeviceSession> *session /*out*/,
+            camera_metadata_t **staticMeta /*out*/);
+    void configurePreviewStream(const std::string &name,
+            const CameraHidlEnvironment* env,
+            const AvailableStream *previewThreshold,
+            sp<ICameraDeviceSession> *session /*out*/,
+            Stream *previewStream /*out*/,
+            HalStreamConfiguration *halStreamConfig /*out*/);
     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
             std::vector<AvailableStream> &outputStreams,
-            AvailableStream *threshold = nullptr);
+            const AvailableStream *threshold = nullptr);
     static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
     static Status pickConstrainedModeSize(camera_metadata_t *staticMeta,
             AvailableStream &hfrStream);
@@ -184,14 +558,114 @@
     static Status findLargestSize(
             const std::vector<AvailableStream> &streamSizes,
             int32_t format, AvailableStream &result);
+    static Status isAutoFocusModeAvailable(
+            ::android::CameraParameters &cameraParams, const char *mode) ;
 
 protected:
     std::mutex mLock;                          // Synchronize access to member variables
     std::condition_variable mResultCondition;  // Condition variable for incoming results
     uint32_t mResultFrameNumber;               // Expected result frame number
     std::vector<StreamBuffer> mResultBuffers;  // Holds stream buffers from capture result
+    std::vector<ErrorMsg> mErrors;             // Holds incoming error notifications
+    DataCallbackMsg mDataMessageTypeReceived;  // Most recent message type received through data callbacks
+    uint32_t mVideoBufferIndex;                // Buffer index of the most recent video buffer
+    uint32_t mVideoData;                       // Buffer data of the most recent video buffer
+    hidl_handle mVideoNativeHandle;            // Most recent video buffer native handle
+    NotifyCallbackMsg mNotifyMessage;          // Current notification message
+
+    std::mutex mTorchLock;                     // Synchronize access to torch status
+    std::condition_variable mTorchCond;        // Condition variable for torch status
+    TorchModeStatus mTorchStatus;              // Current torch status
+
+    // Holds camera registered buffers
+    std::unordered_map<uint32_t, sp<::android::MemoryHeapBase> > mMemoryPool;
 };
 
+Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback(
+        NotifyCallbackMsg msgType, int32_t ext1 __unused,
+        int32_t ext2 __unused) {
+    std::unique_lock<std::mutex> l(mParent->mLock);
+    mParent->mNotifyMessage = msgType;
+    mParent->mResultCondition.notify_one();
+
+    return Void();
+}
+
+Return<uint32_t> CameraHidlTest::Camera1DeviceCb::registerMemory(
+        const hidl_handle& descriptor, uint32_t bufferSize,
+        uint32_t bufferCount) {
+    if (descriptor->numFds != 1) {
+        ADD_FAILURE() << "camera memory descriptor has"
+                " numFds " <<  descriptor->numFds << " (expect 1)" ;
+        return 0;
+    }
+    if (descriptor->data[0] < 0) {
+        ADD_FAILURE() << "camera memory descriptor has"
+                " FD " << descriptor->data[0] << " (expect >= 0)";
+        return 0;
+    }
+
+    sp<::android::MemoryHeapBase> pool = new ::android::MemoryHeapBase(
+            descriptor->data[0], bufferSize*bufferCount, 0, 0);
+    mParent->mMemoryPool.emplace(pool->getHeapID(), pool);
+
+    return pool->getHeapID();
+}
+
+Return<void> CameraHidlTest::Camera1DeviceCb::unregisterMemory(uint32_t memId) {
+    if (mParent->mMemoryPool.count(memId) == 0) {
+        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
+        ADD_FAILURE();
+        return Void();
+    }
+
+    mParent->mMemoryPool.erase(memId);
+    return Void();
+}
+
+Return<void> CameraHidlTest::Camera1DeviceCb::dataCallback(
+        DataCallbackMsg msgType __unused, uint32_t data __unused,
+        uint32_t bufferIndex __unused,
+        const CameraFrameMetadata& metadata __unused) {
+    std::unique_lock<std::mutex> l(mParent->mLock);
+    mParent->mDataMessageTypeReceived = msgType;
+    mParent->mResultCondition.notify_one();
+
+    return Void();
+}
+
+Return<void> CameraHidlTest::Camera1DeviceCb::dataCallbackTimestamp(
+        DataCallbackMsg msgType, uint32_t data,
+        uint32_t bufferIndex, int64_t timestamp __unused) {
+    std::unique_lock<std::mutex> l(mParent->mLock);
+    mParent->mDataMessageTypeReceived = msgType;
+    mParent->mVideoBufferIndex = bufferIndex;
+    if (mParent->mMemoryPool.count(data) == 0) {
+        ADD_FAILURE() << "memory pool ID " << data << "not found";
+    }
+    mParent->mVideoData = data;
+    mParent->mResultCondition.notify_one();
+
+    return Void();
+}
+
+Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestamp(
+        DataCallbackMsg msgType, const hidl_handle& frameData,
+        uint32_t data __unused, uint32_t bufferIndex,
+        int64_t timestamp __unused) {
+    std::unique_lock<std::mutex> l(mParent->mLock);
+    mParent->mDataMessageTypeReceived = msgType;
+    mParent->mVideoBufferIndex = bufferIndex;
+    if (mParent->mMemoryPool.count(data) == 0) {
+        ADD_FAILURE() << "memory pool ID " << data << " not found";
+    }
+    mParent->mVideoData = data;
+    mParent->mVideoNativeHandle = frameData;
+    mParent->mResultCondition.notify_one();
+
+    return Void();
+}
+
 Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
         const CaptureResult& result) {
     if (nullptr == mParent) {
@@ -221,16 +695,28 @@
 }
 
 Return<void> CameraHidlTest::DeviceCb::notify(
-        const NotifyMsg& /*msg*/) {
-    // TODO(epeev): Pending implementation.
-    ALOGI("notify callback");
+        const NotifyMsg& message) {
+
+    if (MsgType::ERROR == message.type) {
+        {
+            std::lock_guard<std::mutex> l(mParent->mLock);
+            mParent->mErrors.push_back(message.msg.error);
+        }
+
+        if ((ErrorCode::ERROR_REQUEST == message.msg.error.errorCode)
+                || (ErrorCode::ERROR_BUFFER == message.msg.error.errorCode)) {
+            mParent->mResultCondition.notify_one();
+        }
+    }
+
     return Void();
 }
 
 hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames() {
     CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     hidl_vec<hidl_string> cameraDeviceNames;
-    env->mProvider->getCameraIdList(
+    Return<void> ret;
+    ret = env->mProvider->getCameraIdList(
         [&](auto status, const auto& idList) {
             ALOGI("getCameraIdList returns status:%d", (int)status);
             for (size_t i = 0; i < idList.size(); i++) {
@@ -239,22 +725,28 @@
             ASSERT_EQ(Status::OK, status);
             cameraDeviceNames = idList;
         });
+    if (!ret.isOk()) {
+        ADD_FAILURE();
+    }
     return cameraDeviceNames;
 }
 
 // Test if ICameraProvider::isTorchModeSupported returns Status::OK
 TEST_F(CameraHidlTest, isTorchModeSupported) {
-    CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
+    Return<void> ret;
+    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
         [&](auto status, bool support) {
             ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
                     (int)status, support);
             ASSERT_EQ(Status::OK, status);
         });
+    ASSERT_TRUE(ret.isOk());
 }
 
 // TODO: consider removing this test if getCameraDeviceNames() has the same coverage
 TEST_F(CameraHidlTest, getCameraIdList) {
-    CameraHidlEnvironment::Instance()->mProvider->getCameraIdList(
+    Return<void> ret;
+    ret = CameraHidlEnvironment::Instance()->mProvider->getCameraIdList(
         [&](auto status, const auto& idList) {
             ALOGI("getCameraIdList returns status:%d", (int)status);
             for (size_t i = 0; i < idList.size(); i++) {
@@ -265,11 +757,13 @@
             // Not necessary hold for external cameras providers
             ASSERT_GT(idList.size(), 0u);
         });
+    ASSERT_TRUE(ret.isOk());
 }
 
 // Test if ICameraProvider::getVendorTags returns Status::OK
 TEST_F(CameraHidlTest, getVendorTags) {
-    CameraHidlEnvironment::Instance()->mProvider->getVendorTags(
+    Return<void> ret;
+    ret = CameraHidlEnvironment::Instance()->mProvider->getVendorTags(
         [&](auto status, const auto& vendorTagSecs) {
             ALOGI("getVendorTags returns status:%d numSections %zu",
                     (int)status, vendorTagSecs.size());
@@ -286,6 +780,7 @@
             }
             ASSERT_EQ(Status::OK, status);
         });
+    ASSERT_TRUE(ret.isOk());
 }
 
 // Test if ICameraProvider::setCallback returns Status::OK
@@ -310,25 +805,36 @@
     };
     sp<ProviderCb> cb = new ProviderCb;
     auto status = env->mProvider->setCallback(cb);
+    ASSERT_TRUE(status.isOk());
     ASSERT_EQ(Status::OK, status);
-    // TODO: right now no callbacks are fired because there is no external camera
-    //       or torch mode change. Need to test torch API in CameraDevice test later.
 }
 
-// Test if ICameraProvider::getCameraDeviceInterface_V3_x returns Status::OK and non-null device
-TEST_F(CameraHidlTest, getCameraDeviceInterface_V3_x) {
+// Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
+TEST_F(CameraHidlTest, getCameraDeviceInterface) {
     CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            env->mProvider->getCameraDeviceInterface_V3_x(
+            Return<void> ret;
+            ret = env->mProvider->getCameraDeviceInterface_V3_x(
                 name,
                 [&](auto status, const auto& device3_2) {
                     ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
                     ASSERT_EQ(Status::OK, status);
                     ASSERT_NE(device3_2, nullptr);
                 });
+            ASSERT_TRUE(ret.isOk());
+        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            Return<void> ret;
+            ret = env->mProvider->getCameraDeviceInterface_V1_x(
+                name,
+                [&](auto status, const auto& device1) {
+                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+                    ASSERT_EQ(Status::OK, status);
+                    ASSERT_NE(device1, nullptr);
+                });
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -343,7 +849,8 @@
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
             ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
             ALOGI("getResourceCost: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
+            Return<void> ret;
+            ret = env->mProvider->getCameraDeviceInterface_V3_x(
                 name,
                 [&](auto status, const auto& device) {
                     ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
@@ -351,8 +858,9 @@
                     ASSERT_NE(device, nullptr);
                     device3_2 = device;
                 });
+            ASSERT_TRUE(ret.isOk());
 
-            device3_2->getResourceCost(
+            ret = device3_2->getResourceCost(
                 [&](auto status, const auto& resourceCost) {
                     ALOGI("getResourceCost returns status:%d", (int)status);
                     ASSERT_EQ(Status::OK, status);
@@ -362,6 +870,759 @@
                         ALOGI("    Conflicting device: %s", name.c_str());
                     }
                 });
+            ASSERT_TRUE(ret.isOk());
+        } else {
+            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            ALOGI("getResourceCost: Testing camera device %s", name.c_str());
+            Return<void> ret;
+            ret = env->mProvider->getCameraDeviceInterface_V1_x(
+                name,
+                [&](auto status, const auto& device) {
+                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+                    ASSERT_EQ(Status::OK, status);
+                    ASSERT_NE(device, nullptr);
+                    device1 = device;
+                });
+            ASSERT_TRUE(ret.isOk());
+
+            ret = device1->getResourceCost(
+                [&](auto status, const auto& resourceCost) {
+                    ALOGI("getResourceCost returns status:%d", (int)status);
+                    ASSERT_EQ(Status::OK, status);
+                    ALOGI("    Resource cost is %d", resourceCost.resourceCost);
+                    ASSERT_LE(resourceCost.resourceCost, 100u);
+                    for (const auto& name : resourceCost.conflictingDevices) {
+                        ALOGI("    Conflicting device: %s", name.c_str());
+                    }
+                });
+            ASSERT_TRUE(ret.isOk());
+        }
+    }
+}
+
+// Verify that the static camera info can be retrieved
+// successfully.
+TEST_F(CameraHidlTest, getCameraInfo) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
+            Return<void> ret;
+            ret = env->mProvider->getCameraDeviceInterface_V1_x(
+                name,
+                [&](auto status, const auto& device) {
+                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+                    ASSERT_EQ(Status::OK, status);
+                    ASSERT_NE(device, nullptr);
+                    device1 = device;
+                });
+            ASSERT_TRUE(ret.isOk());
+
+            ret = device1->getCameraInfo(
+                [&](auto status, const auto& info) {
+                    ALOGI("getCameraInfo returns status:%d", (int)status);
+                    ASSERT_EQ(Status::OK, status);
+                    switch(info.orientation) {
+                        case 0:
+                        case 90:
+                        case 180:
+                        case 270:
+                            //Expected cases
+                            ALOGI("camera orientation: %d", info.orientation);
+                            break;
+                        default:
+                            FAIL() << "Unexpected camera orientation:" << info.orientation;
+                    }
+                    switch(info.facing) {
+                        case CameraFacing::BACK:
+                        case CameraFacing::FRONT:
+                        case CameraFacing::EXTERNAL:
+                            //Expected cases
+                            ALOGI("camera facing: %d", info.facing);
+                            break;
+                        default:
+                            FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> (info.facing);
+                    }
+                });
+            ASSERT_TRUE(ret.isOk());
+        }
+    }
+}
+
+// Check whether preview window can be configured
+TEST_F(CameraHidlTest, setPreviewWindow) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                    openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1,
+                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
+
+            Return<void> ret;
+            ret = device1->close();
+            ASSERT_TRUE(ret.isOk());
+        }
+    }
+}
+
+// Verify that setting preview window fails in case device is not open
+TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
+            Return<void> ret;
+            ret = env->mProvider->getCameraDeviceInterface_V1_x(
+                name,
+                [&](auto status, const auto& device) {
+                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+                    ASSERT_EQ(Status::OK, status);
+                    ASSERT_NE(device, nullptr);
+                    device1 = device;
+                });
+            ASSERT_TRUE(ret.isOk());
+
+            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
+        }
+    }
+}
+
+// Start and stop preview checking whether it gets enabled in between.
+TEST_F(CameraHidlTest, startStopPreview) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                    openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1,
+                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
+
+            startPreview(device1);
+
+            Return<bool> returnBoolStatus = device1->previewEnabled();
+            ASSERT_TRUE(returnBoolStatus.isOk());
+            ASSERT_TRUE(returnBoolStatus);
+
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// Start preview without active preview window. Preview should start as soon
+// as a valid active window gets configured.
+TEST_F(CameraHidlTest, startStopPreviewDelayed) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+
+            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            startPreview(device1);
+
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                    &bufferHandler /*out*/);
+
+            //Preview should get enabled now
+            Return<bool> returnBoolStatus = device1->previewEnabled();
+            ASSERT_TRUE(returnBoolStatus.isOk());
+            ASSERT_TRUE(returnBoolStatus);
+
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// Verify that image capture behaves as expected along with preview callbacks.
+TEST_F(CameraHidlTest, takePicture) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                    &bufferHandler /*out*/);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+            }
+
+            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
+            startPreview(device1);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
+            }
+
+            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                            device1);
+            enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
+                    device1);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+            }
+
+            Return<Status> returnStatus = device1->takePicture();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
+            }
+
+            disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
+                    device1);
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// Image capture should fail in case preview didn't get enabled first.
+TEST_F(CameraHidlTest, takePictureFail) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+
+            Return<Status> returnStatus = device1->takePicture();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_NE(Status::OK, returnStatus);
+
+            Return<void> ret = device1->close();
+            ASSERT_TRUE(ret.isOk());
+        }
+    }
+}
+
+// Verify that image capture can be cancelled.
+TEST_F(CameraHidlTest, cancelPicture) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                    &bufferHandler /*out*/);
+            startPreview(device1);
+
+            Return<Status> returnStatus = device1->takePicture();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            returnStatus = device1->cancelPicture();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// Image capture cancel should fail when image capture is not running.
+TEST_F(CameraHidlTest, cancelPictureFail) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                    &bufferHandler /*out*/);
+            startPreview(device1);
+
+            Return<Status> returnStatus = device1->cancelPicture();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_NE(Status::OK, returnStatus);
+
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// Test basic video recording.
+TEST_F(CameraHidlTest, startStopRecording) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                    &bufferHandler /*out*/);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+            }
+
+            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
+            startPreview(device1);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
+                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                mVideoBufferIndex = UINT32_MAX;
+            }
+
+            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
+
+            bool videoMetaEnabled = false;
+            Return<Status> returnStatus = device1->storeMetaDataInBuffers(true);
+            ASSERT_TRUE(returnStatus.isOk());
+            // It is allowed for devices to not support this feature
+            ASSERT_TRUE((Status::OK == returnStatus) ||
+                    (Status::OPERATION_NOT_SUPPORTED == returnStatus));
+            if (Status::OK == returnStatus) {
+                videoMetaEnabled = true;
+            }
+
+            enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
+            Return<bool> returnBoolStatus = device1->recordingEnabled();
+            ASSERT_TRUE(returnBoolStatus.isOk());
+            ASSERT_FALSE(returnBoolStatus);
+
+            returnStatus = device1->startRecording();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
+                ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
+                disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
+                        device1);
+            }
+
+            returnBoolStatus = device1->recordingEnabled();
+            ASSERT_TRUE(returnBoolStatus.isOk());
+            ASSERT_TRUE(returnBoolStatus);
+
+            Return<void> ret;
+            if (videoMetaEnabled) {
+                ret = device1->releaseRecordingFrameHandle(mVideoData,
+                        mVideoBufferIndex, mVideoNativeHandle);
+                ASSERT_TRUE(ret.isOk());
+            } else {
+                ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex);
+                ASSERT_TRUE(ret.isOk());
+            }
+
+            ret = device1->stopRecording();
+            ASSERT_TRUE(ret.isOk());
+
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// It shouldn't be possible to start recording without enabling preview first.
+TEST_F(CameraHidlTest, startRecordingFail) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+
+            Return<bool> returnBoolStatus = device1->recordingEnabled();
+            ASSERT_TRUE(returnBoolStatus.isOk());
+            ASSERT_FALSE(returnBoolStatus);
+
+            Return<Status> returnStatus = device1->startRecording();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_NE(Status::OK, returnStatus);
+
+            Return<void> ret = device1->close();
+            ASSERT_TRUE(ret.isOk());
+        }
+    }
+}
+
+// Check autofocus support if available.
+TEST_F(CameraHidlTest, autoFocus) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
+            CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
+            CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+
+            ::android::CameraParameters cameraParams;
+            getParameters(device1, &cameraParams /*out*/);
+
+            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
+                    CameraParameters::FOCUS_MODE_AUTO)) {
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+                continue;
+            }
+
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                    &bufferHandler /*out*/);
+            startPreview(device1);
+            enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
+
+            for (auto &iter : focusModes) {
+                if (Status::OK != isAutoFocusModeAvailable(cameraParams,
+                        iter)) {
+                    continue;
+                }
+
+                cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
+                setParameters(device1, cameraParams);
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mNotifyMessage = NotifyCallbackMsg::ERROR;
+                }
+
+                Return<Status> returnStatus = device1->autoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kAutoFocusTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
+                    }
+                }
+            }
+
+            disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// In case autofocus is supported verify that it can be cancelled.
+TEST_F(CameraHidlTest, cancelAutoFocus) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+
+            ::android::CameraParameters cameraParams;
+            getParameters(device1, &cameraParams /*out*/);
+
+            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
+                    CameraParameters::FOCUS_MODE_AUTO)) {
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+                continue;
+            }
+
+            // It should be fine to call before preview starts.
+            ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
+
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                    &bufferHandler /*out*/);
+            startPreview(device1);
+
+            // It should be fine to call after preview starts too.
+            Return<Status> returnStatus = device1->cancelAutoFocus();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            returnStatus = device1->autoFocus();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            returnStatus = device1->cancelAutoFocus();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// Check whether face detection is available and try to enable&disable.
+TEST_F(CameraHidlTest, sendCommandFaceDetection) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+
+            ::android::CameraParameters cameraParams;
+            getParameters(device1, &cameraParams /*out*/);
+
+            int32_t hwFaces = cameraParams.getInt(
+                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
+            int32_t swFaces = cameraParams.getInt(
+                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
+            if ((0 >= hwFaces) && (0 >= swFaces)) {
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+                continue;
+            }
+
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                    &bufferHandler /*out*/);
+            startPreview(device1);
+
+            if (0 < hwFaces) {
+                Return<Status> returnStatus = device1->sendCommand(
+                        CommandType::START_FACE_DETECTION,
+                        CAMERA_FACE_DETECTION_HW, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                // TODO(epeev) : Enable and check for face notifications
+                returnStatus = device1->sendCommand(
+                        CommandType::STOP_FACE_DETECTION,
+                        CAMERA_FACE_DETECTION_HW, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+            }
+
+            if (0 < swFaces) {
+                Return<Status> returnStatus = device1->sendCommand(
+                        CommandType::START_FACE_DETECTION,
+                        CAMERA_FACE_DETECTION_SW, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                // TODO(epeev) : Enable and check for face notifications
+                returnStatus = device1->sendCommand(
+                        CommandType::STOP_FACE_DETECTION,
+                        CAMERA_FACE_DETECTION_SW, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+            }
+
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// Check whether smooth zoom is available and try to enable&disable.
+TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+
+            ::android::CameraParameters cameraParams;
+            getParameters(device1, &cameraParams /*out*/);
+
+            const char *smoothZoomStr = cameraParams.get(
+                    CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
+            bool smoothZoomSupported = ((nullptr != smoothZoomStr) &&
+                    (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ?
+                            true : false;
+            if (!smoothZoomSupported) {
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+                continue;
+            }
+
+            int32_t maxZoom = cameraParams.getInt(
+                    CameraParameters::KEY_MAX_ZOOM);
+            ASSERT_TRUE(0 < maxZoom);
+
+            sp<BufferItemConsumer> bufferItemConsumer;
+            sp<BufferItemHander> bufferHandler;
+            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                    &bufferHandler /*out*/);
+            startPreview(device1);
+            setParameters(device1, cameraParams);
+
+            Return<Status> returnStatus = device1->sendCommand(
+                    CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+            // TODO(epeev) : Enable and check for face notifications
+            returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM,
+                    0, 0);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            stopPreviewAndClose(device1);
+        }
+    }
+}
+
+// Basic sanity tests related to camera parameters.
+TEST_F(CameraHidlTest, getSetParameters) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+
+            ::android::CameraParameters cameraParams;
+            getParameters(device1, &cameraParams /*out*/);
+
+            int32_t width, height;
+            cameraParams.getPictureSize(&width, &height);
+            ASSERT_TRUE((0 < width) && (0 < height));
+            cameraParams.getPreviewSize(&width, &height);
+            ASSERT_TRUE((0 < width) && (0 < height));
+            int32_t minFps, maxFps;
+            cameraParams.getPreviewFpsRange(&minFps, &maxFps);
+            ASSERT_TRUE((0 < minFps) && (0 < maxFps));
+            ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
+            ASSERT_NE(nullptr, cameraParams.getPictureFormat());
+            ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG,
+                    cameraParams.getPictureFormat()) == 0);
+
+            const char *flashMode = cameraParams.get(
+                    CameraParameters::KEY_FLASH_MODE);
+            ASSERT_TRUE((nullptr == flashMode) || (strcmp(
+                    CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
+
+            const char *wbMode = cameraParams.get(
+                    CameraParameters::KEY_WHITE_BALANCE);
+            ASSERT_TRUE((nullptr == wbMode) || (strcmp(
+                    CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
+
+            const char *effect = cameraParams.get(CameraParameters::KEY_EFFECT);
+            ASSERT_TRUE((nullptr == effect) || (strcmp(
+                    CameraParameters::EFFECT_NONE, effect) == 0));
+
+            ::android::Vector<::android::Size> previewSizes;
+            cameraParams.getSupportedPreviewSizes(previewSizes);
+            ASSERT_FALSE(previewSizes.empty());
+            ::android::Vector<::android::Size> pictureSizes;
+            cameraParams.getSupportedPictureSizes(pictureSizes);
+            ASSERT_FALSE(pictureSizes.empty());
+            const char *previewFormats = cameraParams.get(
+                    CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
+            ASSERT_NE(nullptr, previewFormats);
+            ::android::String8 previewFormatsString(previewFormats);
+            ASSERT_TRUE(previewFormatsString.contains(
+                    CameraParameters::PIXEL_FORMAT_YUV420SP));
+            ASSERT_NE(nullptr, cameraParams.get(
+                    CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
+            ASSERT_NE(nullptr, cameraParams.get(
+                    CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
+            const char *focusModes = cameraParams.get(
+                    CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
+            ASSERT_NE(nullptr, focusModes);
+            ::android::String8 focusModesString(focusModes);
+            const char *focusMode = cameraParams.get(
+                    CameraParameters::KEY_FOCUS_MODE);
+            ASSERT_NE(nullptr, focusMode);
+            // Auto focus mode should be default
+            if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) {
+                ASSERT_TRUE(strcmp(
+                        CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
+            }
+            ASSERT_TRUE(0 < cameraParams.getInt(
+                    CameraParameters::KEY_FOCAL_LENGTH));
+            int32_t horizontalViewAngle = cameraParams.getInt(
+                    CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
+            ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle));
+            int32_t verticalViewAngle = cameraParams.getInt(
+                    CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
+            ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle));
+            int32_t jpegQuality = cameraParams.getInt(
+                    CameraParameters::KEY_JPEG_QUALITY);
+            ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
+            int32_t jpegThumbQuality = cameraParams.getInt(
+                    CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
+            ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality));
+
+            cameraParams.setPictureSize(pictureSizes[0].width,
+                    pictureSizes[0].height);
+            cameraParams.setPreviewSize(previewSizes[0].width,
+                    previewSizes[0].height);
+
+            setParameters(device1, cameraParams);
+            getParameters(device1, &cameraParams /*out*/);
+
+            cameraParams.getPictureSize(&width, &height);
+            ASSERT_TRUE((pictureSizes[0].width == width) &&
+                    (pictureSizes[0].height == height));
+            cameraParams.getPreviewSize(&width, &height);
+            ASSERT_TRUE((previewSizes[0].width == width) &&
+                    (previewSizes[0].height == height));
+
+            Return<void> ret = device1->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -376,7 +1637,8 @@
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
             ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
             ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
+            Return<void> ret;
+            ret = env->mProvider->getCameraDeviceInterface_V3_x(
                 name,
                 [&](auto status, const auto& device) {
                     ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
@@ -384,8 +1646,9 @@
                     ASSERT_NE(device, nullptr);
                     device3_2 = device;
                 });
+            ASSERT_TRUE(ret.isOk());
 
-            device3_2->getCameraCharacteristics(
+            ret = device3_2->getCameraCharacteristics(
                 [&](auto status, const auto& chars) {
                     ALOGI("getCameraCharacteristics returns status:%d", (int)status);
                     ASSERT_EQ(Status::OK, status);
@@ -398,17 +1661,20 @@
                     ASSERT_GT(entryCount, 0u);
                     ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
                 });
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
 
 //In case it is supported verify that torch can be enabled.
+//Check for corresponding toch callbacks as well.
 TEST_F(CameraHidlTest, setTorchMode) {
     CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
     bool torchControlSupported = false;
+    Return<void> ret;
 
-    CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
+    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
         [&](auto status, bool support) {
             ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
                     (int)status, support);
@@ -416,11 +1682,17 @@
             torchControlSupported = support;
         });
 
+
+    sp<TorchProviderCb> cb = new TorchProviderCb(this);
+    Return<Status> returnStatus = env->mProvider->setCallback(cb);
+    ASSERT_TRUE(returnStatus.isOk());
+    ASSERT_EQ(Status::OK, returnStatus);
+
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
             ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
             ALOGI("setTorchMode: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
+            ret = env->mProvider->getCameraDeviceInterface_V3_x(
                 name,
                 [&](auto status, const auto& device) {
                     ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
@@ -428,32 +1700,116 @@
                     ASSERT_NE(device, nullptr);
                     device3_2 = device;
                 });
+            ASSERT_TRUE(ret.isOk());
 
-            Status status = device3_2->setTorchMode(TorchMode::ON);
-            ALOGI("setTorchMode return status %d", (int)status);
+            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+            returnStatus = device3_2->setTorchMode(TorchMode::ON);
+            ASSERT_TRUE(returnStatus.isOk());
             if (!torchControlSupported) {
-                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, status);
+                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
             } else {
-                ASSERT_TRUE(status == Status::OK || status == Status::OPERATION_NOT_SUPPORTED);
-                if (status == Status::OK) {
-                    status = device3_2->setTorchMode(TorchMode::OFF);
-                    ASSERT_EQ(Status::OK, status);
+                ASSERT_TRUE(returnStatus == Status::OK ||
+                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
+                if (returnStatus == Status::OK) {
+                    {
+                        std::unique_lock<std::mutex> l(mTorchLock);
+                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                            auto timeout = std::chrono::system_clock::now() +
+                                    std::chrono::seconds(kTorchTimeoutSec);
+                            ASSERT_NE(std::cv_status::timeout,
+                                    mTorchCond.wait_until(l, timeout));
+                        }
+                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
+                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                    }
+
+                    returnStatus = device3_2->setTorchMode(TorchMode::OFF);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+
+                    {
+                        std::unique_lock<std::mutex> l(mTorchLock);
+                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                            auto timeout = std::chrono::system_clock::now() +
+                                    std::chrono::seconds(kTorchTimeoutSec);
+                            ASSERT_NE(std::cv_status::timeout,
+                                    mTorchCond.wait_until(l, timeout));
+                        }
+                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
+                    }
                 }
             }
+        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            ALOGI("dumpState: Testing camera device %s", name.c_str());
+            ret = env->mProvider->getCameraDeviceInterface_V1_x(
+                name,
+                [&](auto status, const auto& device) {
+                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+                    ASSERT_EQ(Status::OK, status);
+                    ASSERT_NE(device, nullptr);
+                    device1 = device;
+                });
+            ASSERT_TRUE(ret.isOk());
+
+            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+            returnStatus = device1->setTorchMode(TorchMode::ON);
+            ASSERT_TRUE(returnStatus.isOk());
+            if (!torchControlSupported) {
+                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+            } else {
+                ASSERT_TRUE(returnStatus == Status::OK ||
+                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
+                if (returnStatus == Status::OK) {
+                    {
+                        std::unique_lock<std::mutex> l(mTorchLock);
+                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                            auto timeout = std::chrono::system_clock::now() +
+                                    std::chrono::seconds(kTorchTimeoutSec);
+                            ASSERT_NE(std::cv_status::timeout,
+                                    mTorchCond.wait_until(l, timeout));
+                        }
+                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
+                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                    }
+
+                    returnStatus = device1->setTorchMode(TorchMode::OFF);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+
+                    {
+                        std::unique_lock<std::mutex> l(mTorchLock);
+                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                            auto timeout = std::chrono::system_clock::now() +
+                                    std::chrono::seconds(kTorchTimeoutSec);
+                            ASSERT_NE(std::cv_status::timeout,
+                                    mTorchCond.wait_until(l, timeout));
+                        }
+                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
+                    }
+                }
+            }
+            ret = device1->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
+
+    returnStatus = env->mProvider->setCallback(nullptr);
+    ASSERT_TRUE(returnStatus.isOk());
+    ASSERT_EQ(Status::OK, returnStatus);
 }
 
 // Check dump functionality.
 TEST_F(CameraHidlTest, dumpState) {
     CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    Return<void> ret;
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
             ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
             ALOGI("dumpState: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
+            ret = env->mProvider->getCameraDeviceInterface_V3_x(
                 name,
                 [&](auto status, const auto& device) {
                     ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
@@ -461,12 +1817,36 @@
                     ASSERT_NE(device, nullptr);
                     device3_2 = device;
                 });
+            ASSERT_TRUE(ret.isOk());
 
             native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(DUMP_OUTPUT, O_RDWR);
+            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
             ASSERT_GE(raw_handle->data[0], 0);
             hidl_handle handle = raw_handle;
-            device3_2->dumpState(handle);
+            ret= device3_2->dumpState(handle);
+            ASSERT_TRUE(ret.isOk());
+            close(raw_handle->data[0]);
+            native_handle_delete(raw_handle);
+        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            ALOGI("dumpState: Testing camera device %s", name.c_str());
+            ret = env->mProvider->getCameraDeviceInterface_V1_x(
+                name,
+                [&](auto status, const auto& device) {
+                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+                    ASSERT_EQ(Status::OK, status);
+                    ASSERT_NE(device, nullptr);
+                    device1 = device;
+                });
+            ASSERT_TRUE(ret.isOk());
+
+            native_handle_t* raw_handle = native_handle_create(1, 0);
+            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+            ASSERT_GE(raw_handle->data[0], 0);
+            hidl_handle handle = raw_handle;
+            Return<Status> returnStatus = device1->dumpState(handle);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
             close(raw_handle->data[0]);
             native_handle_delete(raw_handle);
         }
@@ -477,12 +1857,13 @@
 TEST_F(CameraHidlTest, openClose) {
     CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    Return<void> ret;
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
             ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
             ALOGI("openClose: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
+            ret = env->mProvider->getCameraDeviceInterface_V3_x(
                 name,
                 [&](auto status, const auto& device) {
                     ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
@@ -490,10 +1871,11 @@
                     ASSERT_NE(device, nullptr);
                     device3_2 = device;
                 });
+            ASSERT_TRUE(ret.isOk());
 
             sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
             sp<ICameraDeviceSession> session;
-            device3_2->open(
+            ret = device3_2->open(
                 cb,
                 [&](auto status, const auto& newSession) {
                     ALOGI("device::open returns status:%d", (int)status);
@@ -501,18 +1883,38 @@
                     ASSERT_NE(newSession, nullptr);
                     session = newSession;
                 });
+            ASSERT_TRUE(ret.isOk());
 
             native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(DUMP_OUTPUT, O_RDWR);
+            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
             ASSERT_GE(raw_handle->data[0], 0);
             hidl_handle handle = raw_handle;
-            device3_2->dumpState(handle);
+            ret = device3_2->dumpState(handle);
+            ASSERT_TRUE(ret.isOk());
             close(raw_handle->data[0]);
             native_handle_delete(raw_handle);
 
-            session->close();
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
             // TODO: test all session API calls return INTERNAL_ERROR after close
             // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
+        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
+            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+            openCameraDevice(name, env, &device1 /*out*/);
+            ASSERT_NE(nullptr, device1.get());
+
+            native_handle_t* raw_handle = native_handle_create(1, 0);
+            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+            ASSERT_GE(raw_handle->data[0], 0);
+            hidl_handle handle = raw_handle;
+            Return<Status> returnStatus = device1->dumpState(handle);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+            close(raw_handle->data[0]);
+            native_handle_delete(raw_handle);
+
+            ret = device1->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -526,8 +1928,9 @@
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
             ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+            Return<void> ret;
             ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
+            ret = env->mProvider->getCameraDeviceInterface_V3_x(
                 name,
                 [&](auto status, const auto& device) {
                     ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
@@ -535,10 +1938,11 @@
                     ASSERT_NE(device, nullptr);
                     device3_2 = device;
                 });
+            ASSERT_TRUE(ret.isOk());
 
             sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
             sp<ICameraDeviceSession> session;
-            device3_2->open(
+            ret = device3_2->open(
                 cb,
                 [&](auto status, const auto& newSession) {
                     ALOGI("device::open returns status:%d", (int)status);
@@ -546,11 +1950,12 @@
                     ASSERT_NE(newSession, nullptr);
                     session = newSession;
                 });
+            ASSERT_TRUE(ret.isOk());
 
             for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW;
                     t <= (uint32_t) RequestTemplate::MANUAL; t++) {
                 RequestTemplate reqTemplate = (RequestTemplate) t;
-                session->constructDefaultRequestSettings(
+                ret = session->constructDefaultRequestSettings(
                     reqTemplate,
                     [&](auto status, const auto& req) {
                         ALOGI("constructDefaultRequestSettings returns status:%d", (int)status);
@@ -577,8 +1982,10 @@
                             ASSERT_EQ(0u, req.size());
                         }
                     });
+                ASSERT_TRUE(ret.isOk());
             }
-            session->close();
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -592,35 +1999,12 @@
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("configureStreams: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-
             camera_metadata_t *staticMeta;
-            device3_2->getCameraCharacteristics([&] (Status s,
-                    CameraMetadata metadata) {
-                ASSERT_EQ(Status::OK, s);
-                staticMeta =
-                        reinterpret_cast<camera_metadata_t*>(metadata.data());
-            });
+            Return<void> ret;
+            sp<ICameraDeviceSession> session;
+            openEmptyDeviceSession(name, env, &session /*out*/,
+                    &staticMeta /*out*/);
+
             outputStreams.clear();
             ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
                     outputStreams));
@@ -636,16 +2020,19 @@
                 ::android::hardware::hidl_vec<Stream> streams = {stream};
                 StreamConfiguration config = {streams,
                         StreamConfigurationMode::NORMAL_MODE};
-                session->configureStreams(config, [streamId] (Status s,
+                ret = session->configureStreams(config, [streamId] (Status s,
                         HalStreamConfiguration halConfig) {
                     ASSERT_EQ(Status::OK, s);
                     ASSERT_EQ(1u, halConfig.streams.size());
                     ASSERT_EQ(halConfig.streams[0].id, streamId);
                 });
+                ASSERT_TRUE(ret.isOk());
                 streamId++;
             }
 
-            session->close();
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -658,35 +2045,12 @@
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("configureStreams: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-
             camera_metadata_t *staticMeta;
-            device3_2->getCameraCharacteristics([&] (Status s,
-                    CameraMetadata metadata) {
-                ASSERT_EQ(Status::OK, s);
-                staticMeta =
-                        reinterpret_cast<camera_metadata_t*>(metadata.data());
-            });
+            Return<void> ret;
+            sp<ICameraDeviceSession> session;
+            openEmptyDeviceSession(name, env, &session /*out*/,
+                    &staticMeta /*out*/);
+
             outputStreams.clear();
             ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
                     outputStreams));
@@ -701,10 +2065,12 @@
             ::android::hardware::hidl_vec<Stream> streams = {stream};
             StreamConfiguration config = {streams,
                     StreamConfigurationMode::NORMAL_MODE};
-            session->configureStreams(config, [] (Status s,
+            ret = session->configureStreams(config, [] (Status s,
                     HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+                            (Status::INTERNAL_ERROR == s));
             });
+            ASSERT_TRUE(ret.isOk());
 
             stream = {streamId++, StreamType::OUTPUT,
                     static_cast<uint32_t> (UINT32_MAX),
@@ -714,10 +2080,11 @@
             streams[0] = stream;
             config = {streams,
                     StreamConfigurationMode::NORMAL_MODE};
-            session->configureStreams(config, [] (Status s,
+            ret = session->configureStreams(config, [] (Status s,
                     HalStreamConfiguration) {
                 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
             });
+            ASSERT_TRUE(ret.isOk());
 
             for (auto &it : outputStreams) {
                 stream = {streamId++, StreamType::OUTPUT,
@@ -728,10 +2095,11 @@
                 streams[0] = stream;
                 config = {streams,
                         StreamConfigurationMode::NORMAL_MODE};
-                session->configureStreams(config, [] (Status s,
+                ret = session->configureStreams(config, [] (Status s,
                         HalStreamConfiguration) {
                     ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
                 });
+                ASSERT_TRUE(ret.isOk());
 
                 stream = {streamId++, StreamType::OUTPUT,
                         static_cast<uint32_t> (it.width),
@@ -741,13 +2109,16 @@
                 streams[0] = stream;
                 config = {streams,
                         StreamConfigurationMode::NORMAL_MODE};
-                session->configureStreams(config, [] (Status s,
+                ret = session->configureStreams(config, [] (Status s,
                         HalStreamConfiguration) {
                     ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
                 });
+                ASSERT_TRUE(ret.isOk());
             }
 
-            session->close();
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -762,41 +2133,19 @@
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("configureStreams: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-
             camera_metadata_t *staticMeta;
-            device3_2->getCameraCharacteristics([&] (Status s,
-                    CameraMetadata metadata) {
-                ASSERT_EQ(Status::OK, s);
-                staticMeta =
-                        reinterpret_cast<camera_metadata_t*>(metadata.data());
-            });
-            Status ret = isZSLModeAvailable(staticMeta);
-            if (Status::METHOD_NOT_SUPPORTED == ret) {
-                session->close();
+            Return<void> ret;
+            sp<ICameraDeviceSession> session;
+            openEmptyDeviceSession(name, env, &session /*out*/,
+                    &staticMeta /*out*/);
+
+            Status rc = isZSLModeAvailable(staticMeta);
+            if (Status::METHOD_NOT_SUPPORTED == rc) {
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
                 continue;
             }
-            ASSERT_EQ(Status::OK, ret);
+            ASSERT_EQ(Status::OK, rc);
 
             inputStreams.clear();
             ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
@@ -842,15 +2191,18 @@
                             inputStream, zslStream, outputStream};
                     StreamConfiguration config = {streams,
                             StreamConfigurationMode::NORMAL_MODE};
-                    session->configureStreams(config, [streamId] (Status s,
+                    ret = session->configureStreams(config, [streamId] (Status s,
                             HalStreamConfiguration halConfig) {
                         ASSERT_EQ(Status::OK, s);
                         ASSERT_EQ(3u, halConfig.streams.size());
                     });
+                    ASSERT_TRUE(ret.isOk());
                 }
             }
 
-            session->close();
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -862,42 +2214,19 @@
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
     std::vector<AvailableStream> outputBlobStreams;
     std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT,
+    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
             static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
     AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
             static_cast<int32_t>(PixelFormat::BLOB)};
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("configureStreams: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-
             camera_metadata_t *staticMeta;
-            device3_2->getCameraCharacteristics([&] (Status s,
-                    CameraMetadata metadata) {
-                ASSERT_EQ(Status::OK, s);
-                staticMeta =
-                        reinterpret_cast<camera_metadata_t*>(metadata.data());
-            });
+            Return<void> ret;
+            sp<ICameraDeviceSession> session;
+            openEmptyDeviceSession(name, env, &session /*out*/,
+                    &staticMeta /*out*/);
+
             outputBlobStreams.clear();
             ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
                     outputBlobStreams, &blobThreshold));
@@ -925,15 +2254,18 @@
                             previewStream, blobStream};
                     StreamConfiguration config = {streams,
                             StreamConfigurationMode::NORMAL_MODE};
-                    session->configureStreams(config, [streamId] (Status s,
+                    ret = session->configureStreams(config, [streamId] (Status s,
                             HalStreamConfiguration halConfig) {
                         ASSERT_EQ(Status::OK, s);
                         ASSERT_EQ(2u, halConfig.streams.size());
                     });
+                    ASSERT_TRUE(ret.isOk());
                 }
             }
 
-            session->close();
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -947,38 +2279,16 @@
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("configureStreams: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-
             camera_metadata_t *staticMeta;
-            device3_2->getCameraCharacteristics([&] (Status s,
-                    CameraMetadata metadata) {
-                ASSERT_EQ(Status::OK, s);
-                staticMeta =
-                        reinterpret_cast<camera_metadata_t*>(metadata.data());
-            });
+            Return<void> ret;
+            sp<ICameraDeviceSession> session;
+            openEmptyDeviceSession(name, env, &session /*out*/,
+                    &staticMeta /*out*/);
+
             Status rc = isConstrainedModeAvailable(staticMeta);
             if (Status::METHOD_NOT_SUPPORTED == rc) {
-                session->close();
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
                 continue;
             }
             ASSERT_EQ(Status::OK, rc);
@@ -996,12 +2306,13 @@
             ::android::hardware::hidl_vec<Stream> streams = {stream};
             StreamConfiguration config = {streams,
                     StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            session->configureStreams(config, [streamId] (Status s,
+            ret = session->configureStreams(config, [streamId] (Status s,
                     HalStreamConfiguration halConfig) {
                 ASSERT_EQ(Status::OK, s);
                 ASSERT_EQ(1u, halConfig.streams.size());
                 ASSERT_EQ(halConfig.streams[0].id, streamId);
             });
+            ASSERT_TRUE(ret.isOk());
 
             stream = {streamId++, StreamType::OUTPUT,
                     static_cast<uint32_t> (0),
@@ -1011,10 +2322,12 @@
             streams[0] = stream;
             config = {streams,
                     StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            session->configureStreams(config, [streamId] (Status s,
+            ret = session->configureStreams(config, [streamId] (Status s,
                     HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+                            (Status::INTERNAL_ERROR == s));
             });
+            ASSERT_TRUE(ret.isOk());
 
             stream = {streamId++, StreamType::OUTPUT,
                     static_cast<uint32_t> (UINT32_MAX),
@@ -1024,10 +2337,11 @@
             streams[0] = stream;
             config = {streams,
                     StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            session->configureStreams(config, [streamId] (Status s,
+            ret = session->configureStreams(config, [streamId] (Status s,
                     HalStreamConfiguration) {
                 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
             });
+            ASSERT_TRUE(ret.isOk());
 
             stream = {streamId++, StreamType::OUTPUT,
                     static_cast<uint32_t> (hfrStream.width),
@@ -1037,12 +2351,15 @@
             streams[0] = stream;
             config = {streams,
                     StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            session->configureStreams(config, [streamId] (Status s,
+            ret = session->configureStreams(config, [streamId] (Status s,
                     HalStreamConfiguration) {
                 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
             });
+            ASSERT_TRUE(ret.isOk());
 
-            session->close();
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -1054,42 +2371,19 @@
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
     std::vector<AvailableStream> outputBlobStreams;
     std::vector<AvailableStream> outputVideoStreams;
-    AvailableStream videoThreshold = {MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT,
+    AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
             static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    AvailableStream blobThreshold = {MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT,
+    AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
             static_cast<int32_t>(PixelFormat::BLOB)};
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("configureStreams: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-
             camera_metadata_t *staticMeta;
-            device3_2->getCameraCharacteristics([&] (Status s,
-                    CameraMetadata metadata) {
-                ASSERT_EQ(Status::OK, s);
-                staticMeta =
-                        reinterpret_cast<camera_metadata_t*>(metadata.data());
-            });
+            Return<void> ret;
+            sp<ICameraDeviceSession> session;
+            openEmptyDeviceSession(name, env, &session /*out*/,
+                    &staticMeta /*out*/);
+
             outputBlobStreams.clear();
             ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
                     outputBlobStreams, &blobThreshold));
@@ -1118,15 +2412,18 @@
                             videoStream, blobStream};
                     StreamConfiguration config = {streams,
                             StreamConfigurationMode::NORMAL_MODE};
-                    session->configureStreams(config, [streamId] (Status s,
+                    ret = session->configureStreams(config, [streamId] (Status s,
                             HalStreamConfiguration halConfig) {
                         ASSERT_EQ(Status::OK, s);
                         ASSERT_EQ(2u, halConfig.streams.size());
                     });
+                    ASSERT_TRUE(ret.isOk());
                 }
             }
 
-            session->close();
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -1135,72 +2432,28 @@
 TEST_F(CameraHidlTest, processCaptureRequestPreview) {
     CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT,
+    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
             static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    int32_t streamId = 0;
     uint64_t bufferId = 1;
     uint32_t frameNumber = 1;
     ::android::hardware::hidl_vec<uint8_t> settings;
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("configureStreams: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-
-            sp<DeviceCb> cb = new DeviceCb(this);
-            sp<ICameraDeviceSession> session;
-            device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-
-            camera_metadata_t *staticMeta;
-            device3_2->getCameraCharacteristics([&] (Status s,
-                    CameraMetadata metadata) {
-                ASSERT_EQ(Status::OK, s);
-                staticMeta =
-                        reinterpret_cast<camera_metadata_t*>(metadata.data());
-            });
-
-            outputPreviewStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputPreviewStreams, &previewThreshold));
-            ASSERT_NE(0u, outputPreviewStreams.size());
-
+            Stream previewStream;
             HalStreamConfiguration halStreamConfig;
-            Stream previewStream = {streamId, StreamType::OUTPUT,
-                    static_cast<uint32_t> (outputPreviewStreams[0].width),
-                    static_cast<uint32_t> (outputPreviewStreams[0].height),
-                    static_cast<PixelFormat> (outputPreviewStreams[0].format),
-                    0, 0, StreamRotation::ROTATION_0};
-            ::android::hardware::hidl_vec<Stream> streams = {previewStream};
-            StreamConfiguration config = {streams,
-                    StreamConfigurationMode::NORMAL_MODE};
-            session->configureStreams(config, [&] (Status s,
-                    HalStreamConfiguration halConfig) {
-                ASSERT_EQ(Status::OK, s);
-                ASSERT_EQ(1u, halConfig.streams.size());
-                halStreamConfig = halConfig;
-            });
+            sp<ICameraDeviceSession> session;
+            configurePreviewStream(name, env, &previewThreshold,
+                    &session /*out*/, &previewStream /*out*/,
+                    &halStreamConfig /*out*/);
 
             RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            session->constructDefaultRequestSettings(reqTemplate,
+            Return<void> ret;
+            ret = session->constructDefaultRequestSettings(reqTemplate,
                 [&](auto status, const auto& req) {
                     ASSERT_EQ(Status::OK, status);
                     settings = req; });
+            ASSERT_TRUE(ret.isOk());
 
             sp<GraphicBuffer> gb = new GraphicBuffer(previewStream.width,
                     previewStream.height,
@@ -1213,49 +2466,61 @@
                     BufferStatus::OK, nullptr, nullptr};
             ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
                     outputBuffer};
+            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                    BufferStatus::ERROR, nullptr, nullptr};
             CaptureRequest request = {frameNumber, settings,
-                    {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr},
-                    outputBuffers};
+                    emptyInputBuffer, outputBuffers};
 
-            std::unique_lock<std::mutex> l(mLock);
-            mResultBuffers.clear();
-            mResultFrameNumber = frameNumber;
-            l.unlock();
-
-            ASSERT_EQ(Status::OK, session->processCaptureRequest(request));
-
-            l.lock();
-            while (0 == mResultBuffers.size()) {
-                auto timeout = std::chrono::system_clock::now() +
-                        std::chrono::seconds(STREAM_BUFFER_TIMEOUT);
-                ASSERT_NE(std::cv_status::timeout,
-                        mResultCondition.wait_until(l, timeout));
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                mResultBuffers.clear();
+                mResultFrameNumber = frameNumber;
             }
 
-            ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
-            ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
+            Return<Status> returnStatus = session->processCaptureRequest(
+                    request);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
 
-            request.frameNumber++;
-            //Empty settings should be supported after the first call
-            //for repeating requests.
-            request.settings.setToExternal(nullptr, 0, true);
-            mResultBuffers.clear();
-            mResultFrameNumber++;
-            l.unlock();
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                while (0 == mResultBuffers.size()) {
+                    auto timeout = std::chrono::system_clock::now() +
+                            std::chrono::seconds(kStreamBufferTimeoutSec);
+                    ASSERT_NE(std::cv_status::timeout,
+                            mResultCondition.wait_until(l, timeout));
+                }
 
-            ASSERT_EQ(Status::OK, session->processCaptureRequest(request));
+                ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
+                ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
 
-            l.lock();
-            while (0 == mResultBuffers.size()) {
-                auto timeout = std::chrono::system_clock::now() +
-                        std::chrono::seconds(STREAM_BUFFER_TIMEOUT);
-                ASSERT_NE(std::cv_status::timeout,
-                        mResultCondition.wait_until(l, timeout));
+                request.frameNumber++;
+                //Empty settings should be supported after the first call
+                //for repeating requests.
+                request.settings.setToExternal(nullptr, 0, true);
+                mResultBuffers.clear();
+                mResultFrameNumber++;
             }
-            ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
-            ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
 
-            session->close();
+            returnStatus = session->processCaptureRequest(
+                    request);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                while (0 == mResultBuffers.size()) {
+                    auto timeout = std::chrono::system_clock::now() +
+                            std::chrono::seconds(kStreamBufferTimeoutSec);
+                    ASSERT_NE(std::cv_status::timeout,
+                            mResultCondition.wait_until(l, timeout));
+                }
+                ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
+                ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
+            }
+
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -1266,65 +2531,20 @@
     CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
     std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT,
+    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
             static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    int32_t streamId = 0;
     uint64_t bufferId = 1;
     uint32_t frameNumber = 1;
     ::android::hardware::hidl_vec<uint8_t> settings;
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("configureStreams: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-
-            sp<DeviceCb> cb = new DeviceCb(this);
-            sp<ICameraDeviceSession> session;
-            device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-
-            camera_metadata_t *staticMeta;
-            device3_2->getCameraCharacteristics([&] (Status s,
-                    CameraMetadata metadata) {
-                ASSERT_EQ(Status::OK, s);
-                staticMeta =
-                        reinterpret_cast<camera_metadata_t*>(metadata.data());
-            });
-
-            outputPreviewStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputPreviewStreams, &previewThreshold));
-            ASSERT_NE(0u, outputPreviewStreams.size());
-
+            Stream previewStream;
             HalStreamConfiguration halStreamConfig;
-            Stream previewStream = {streamId, StreamType::OUTPUT,
-                    static_cast<uint32_t> (outputPreviewStreams[0].width),
-                    static_cast<uint32_t> (outputPreviewStreams[0].height),
-                    static_cast<PixelFormat> (outputPreviewStreams[0].format),
-                    0, 0, StreamRotation::ROTATION_0};
-            ::android::hardware::hidl_vec<Stream> streams = {previewStream};
-            StreamConfiguration config = {streams,
-                    StreamConfigurationMode::NORMAL_MODE};
-            session->configureStreams(config, [&] (Status s,
-                    HalStreamConfiguration halConfig) {
-                ASSERT_EQ(Status::OK, s);
-                ASSERT_EQ(1u, halConfig.streams.size());
-                halStreamConfig = halConfig;
-            });
+            sp<ICameraDeviceSession> session;
+            configurePreviewStream(name, env, &previewThreshold,
+                    &session /*out*/, &previewStream /*out*/,
+                    &halStreamConfig /*out*/);
 
             sp<GraphicBuffer> gb = new GraphicBuffer(previewStream.width,
                     previewStream.height,
@@ -1337,104 +2557,208 @@
                     BufferStatus::OK, nullptr, nullptr};
             ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
                     outputBuffer};
+            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                    BufferStatus::ERROR, nullptr, nullptr};
             CaptureRequest request = {frameNumber, settings,
-                    {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr},
-                    outputBuffers};
+                    emptyInputBuffer, outputBuffers};
 
             //Settings were not correctly initialized, we should fail here
-            ASSERT_EQ(Status::INTERNAL_ERROR,
-                    session->processCaptureRequest(request));
+            Return<Status> returnStatus = session->processCaptureRequest(
+                    request);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::INTERNAL_ERROR, returnStatus);
 
-            session->close();
+            Return<void> ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
 
 // Check whether an invalid capture request with missing output buffers
 // will be reported correctly.
-TEST_F(CameraHidlTest, processCaptureRequestInvalidSingleSnapshot) {
+TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
     CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
     std::vector<AvailableStream> outputBlobStreams;
-    AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
-            static_cast<int32_t>(PixelFormat::BLOB)};
-    int32_t streamId = 0;
+    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+    uint32_t frameNumber = 1;
+    ::android::hardware::hidl_vec<uint8_t> settings;
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
+            Stream previewStream;
+            HalStreamConfiguration halStreamConfig;
+            sp<ICameraDeviceSession> session;
+            configurePreviewStream(name, env, &previewThreshold,
+                    &session /*out*/, &previewStream /*out*/,
+                    &halStreamConfig /*out*/);
+
+            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+            Return<void> ret;
+            ret = session->constructDefaultRequestSettings(reqTemplate,
+                [&](auto status, const auto& req) {
+                    ASSERT_EQ(Status::OK, status);
+                    settings = req; });
+            ASSERT_TRUE(ret.isOk());
+
+            ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
+            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                    BufferStatus::ERROR, nullptr, nullptr};
+            CaptureRequest request = {frameNumber, settings,
+                    emptyInputBuffer, emptyOutputBuffers};
+
+            //Output buffers are missing, we should fail here
+            Return<Status> returnStatus = session->processCaptureRequest(
+                    request);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::INTERNAL_ERROR,
+                      returnStatus);
+
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+        }
+    }
+}
+
+// Generate, trigger and flush a preview request
+TEST_F(CameraHidlTest, flushPreviewRequest) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    std::vector<AvailableStream> outputPreviewStreams;
+    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
     uint64_t bufferId = 1;
     uint32_t frameNumber = 1;
     ::android::hardware::hidl_vec<uint8_t> settings;
 
     for (const auto& name : cameraDeviceNames) {
         if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("configureStreams: Testing camera device %s", name.c_str());
-            env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-
-            sp<DeviceCb> cb = new DeviceCb(this);
-            sp<ICameraDeviceSession> session;
-            device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-
-            camera_metadata_t *staticMeta;
-            device3_2->getCameraCharacteristics([&] (Status s,
-                    CameraMetadata metadata) {
-                ASSERT_EQ(Status::OK, s);
-                staticMeta =
-                        reinterpret_cast<camera_metadata_t*>(metadata.data());
-            });
-
-            outputBlobStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputBlobStreams, &blobThreshold));
-            ASSERT_NE(0u, outputBlobStreams.size());
-
+            Stream previewStream;
             HalStreamConfiguration halStreamConfig;
-            Stream previewStream = {streamId, StreamType::OUTPUT,
-                    static_cast<uint32_t> (outputBlobStreams[0].width),
-                    static_cast<uint32_t> (outputBlobStreams[0].height),
-                    static_cast<PixelFormat> (outputBlobStreams[0].format),
-                    0, 0, StreamRotation::ROTATION_0};
-            ::android::hardware::hidl_vec<Stream> streams = {previewStream};
-            StreamConfiguration config = {streams,
-                    StreamConfigurationMode::NORMAL_MODE};
-            session->configureStreams(config, [&] (Status s,
-                    HalStreamConfiguration halConfig) {
-                ASSERT_EQ(Status::OK, s);
-                ASSERT_EQ(1u, halConfig.streams.size());
-                halStreamConfig = halConfig;
-            });
+            sp<ICameraDeviceSession> session;
+            configurePreviewStream(name, env, &previewThreshold,
+                    &session /*out*/, &previewStream /*out*/,
+                    &halStreamConfig /*out*/);
 
-            RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE;
-            session->constructDefaultRequestSettings(reqTemplate,
+            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+            Return<void> ret;
+            ret = session->constructDefaultRequestSettings(reqTemplate,
                 [&](auto status, const auto& req) {
                     ASSERT_EQ(Status::OK, status);
                     settings = req; });
+            ASSERT_TRUE(ret.isOk());
 
+            sp<GraphicBuffer> gb = new GraphicBuffer(previewStream.width,
+                    previewStream.height,
+                    static_cast<int32_t> (halStreamConfig.streams[0].overrideFormat),
+                    1, halStreamConfig.streams[0].producerUsage,
+                    halStreamConfig.streams[0].consumerUsage);
+            ASSERT_NE(nullptr, gb.get());
             StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(nullptr), BufferStatus::OK,
-                    nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers;
+                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                    BufferStatus::OK, nullptr, nullptr};
+            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                    outputBuffer};
+            const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                    BufferStatus::ERROR, nullptr, nullptr};
             CaptureRequest request = {frameNumber, settings,
-                    {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr},
-                    outputBuffers};
+                    emptyInputBuffer, outputBuffers};
 
-            //Output buffers are missing, we should fail here
-            ASSERT_EQ(Status::INTERNAL_ERROR,
-                    session->processCaptureRequest(request));
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                mResultBuffers.clear();
+                mErrors.clear();
+                mResultFrameNumber = frameNumber;
+            }
 
-            session->close();
+            Return<Status> returnStatus = session->processCaptureRequest(
+                    request);
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+            //Flush before waiting for request to complete.
+            returnStatus = session->flush();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                while ((0 == mResultBuffers.size()) && (0 == mErrors.size())) {
+                    auto timeout = std::chrono::system_clock::now() +
+                            std::chrono::seconds(kStreamBufferTimeoutSec);
+                    ASSERT_NE(std::cv_status::timeout,
+                            mResultCondition.wait_until(l, timeout));
+                }
+
+                if (mErrors.empty()) {
+                    ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
+                    ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
+                } else {
+                    for (auto &error : mErrors) {
+                        switch (error.errorCode) {
+                            case ErrorCode::ERROR_REQUEST:
+                            case ErrorCode::ERROR_RESULT:
+                                //Expected
+                                break;
+                            case ErrorCode::ERROR_BUFFER:
+                                //Expected as well
+                                ASSERT_EQ(frameNumber, error.frameNumber);
+                                ASSERT_EQ(previewStream.id, error.errorStreamId);
+                                break;
+                            case ErrorCode::ERROR_DEVICE:
+                            default:
+                                FAIL() <<"Unexpected error:" << static_cast<uint32_t> (error.errorCode);
+                        }
+                    }
+                }
+            }
+
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+        }
+    }
+}
+
+// Verify that camera flushes correctly without any pending requests.
+TEST_F(CameraHidlTest, flushEmpty) {
+    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    std::vector<AvailableStream> outputPreviewStreams;
+    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+
+    for (const auto& name : cameraDeviceNames) {
+        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
+            Stream previewStream;
+            HalStreamConfiguration halStreamConfig;
+            sp<ICameraDeviceSession> session;
+            configurePreviewStream(name, env, &previewThreshold,
+                    &session /*out*/, &previewStream /*out*/,
+                    &halStreamConfig /*out*/);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                mResultBuffers.clear();
+                mErrors.clear();
+                mResultFrameNumber = 0;
+            }
+
+            Return<Status> returnStatus = session->flush();
+            ASSERT_TRUE(returnStatus.isOk());
+            ASSERT_EQ(Status::OK, returnStatus);
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                auto timeout = std::chrono::system_clock::now() +
+                        std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
+                ASSERT_EQ(std::cv_status::timeout,
+                        mResultCondition.wait_until(l, timeout));
+                ASSERT_TRUE(mErrors.empty());
+                ASSERT_TRUE(mResultBuffers.empty());
+            }
+
+            Return<void> ret = session->close();
+            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -1443,7 +2767,7 @@
 // static characteristics.
 Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
         std::vector<AvailableStream> &outputStreams,
-        AvailableStream *threshold) {
+        const AvailableStream *threshold) {
     if (nullptr == staticMeta) {
         return Status::ILLEGAL_ARGUMENT;
     }
@@ -1609,6 +2933,260 @@
     return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT;
 }
 
+// Check whether the camera device supports specific focus mode.
+Status CameraHidlTest::isAutoFocusModeAvailable(
+        ::android::CameraParameters &cameraParams,
+        const char *mode) {
+    ::android::String8 focusModes(cameraParams.get(
+            CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
+    if (focusModes.contains(mode)) {
+        return Status::OK;
+    }
+
+    return Status::METHOD_NOT_SUPPORTED;
+}
+
+// Open a device session and configure a preview stream.
+void CameraHidlTest::configurePreviewStream(const std::string &name,
+        const CameraHidlEnvironment* env,
+        const AvailableStream *previewThreshold,
+        sp<ICameraDeviceSession> *session /*out*/,
+        Stream *previewStream /*out*/,
+        HalStreamConfiguration *halStreamConfig /*out*/) {
+    ASSERT_NE(nullptr, env);
+    ASSERT_NE(nullptr, session);
+    ASSERT_NE(nullptr, previewStream);
+    ASSERT_NE(nullptr, halStreamConfig);
+
+    std::vector<AvailableStream> outputPreviewStreams;
+    ::android::sp<ICameraDevice> device3_2;
+    ALOGI("configureStreams: Testing camera device %s", name.c_str());
+    Return<void> ret;
+    ret = env->mProvider->getCameraDeviceInterface_V3_x(
+        name,
+        [&](auto status, const auto& device) {
+            ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                  (int)status);
+            ASSERT_EQ(Status::OK, status);
+            ASSERT_NE(device, nullptr);
+            device3_2 = device;
+        });
+    ASSERT_TRUE(ret.isOk());
+
+    sp<DeviceCb> cb = new DeviceCb(this);
+    ret = device3_2->open(
+        cb,
+        [&](auto status, const auto& newSession) {
+            ALOGI("device::open returns status:%d", (int)status);
+            ASSERT_EQ(Status::OK, status);
+            ASSERT_NE(newSession, nullptr);
+            *session = newSession;
+        });
+    ASSERT_TRUE(ret.isOk());
+
+    camera_metadata_t *staticMeta;
+    ret = device3_2->getCameraCharacteristics([&] (Status s,
+            CameraMetadata metadata) {
+        ASSERT_EQ(Status::OK, s);
+        staticMeta = clone_camera_metadata(
+                reinterpret_cast<const camera_metadata_t*>(metadata.data()));
+         ASSERT_NE(nullptr, staticMeta);
+    });
+    ASSERT_TRUE(ret.isOk());
+
+    outputPreviewStreams.clear();
+    auto rc = getAvailableOutputStreams(staticMeta,
+            outputPreviewStreams, previewThreshold);
+    free_camera_metadata(staticMeta);
+    ASSERT_EQ(Status::OK, rc);
+    ASSERT_FALSE(outputPreviewStreams.empty());
+
+    *previewStream = {0, StreamType::OUTPUT,
+            static_cast<uint32_t> (outputPreviewStreams[0].width),
+            static_cast<uint32_t> (outputPreviewStreams[0].height),
+            static_cast<PixelFormat> (outputPreviewStreams[0].format),
+            0, 0, StreamRotation::ROTATION_0};
+    ::android::hardware::hidl_vec<Stream> streams = {*previewStream};
+    StreamConfiguration config = {streams,
+            StreamConfigurationMode::NORMAL_MODE};
+    ret = (*session)->configureStreams(config, [&] (Status s,
+            HalStreamConfiguration halConfig) {
+        ASSERT_EQ(Status::OK, s);
+        ASSERT_EQ(1u, halConfig.streams.size());
+        *halStreamConfig = halConfig;
+    });
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Open a device session with empty callbacks and return static metadata.
+void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
+        const CameraHidlEnvironment* env,
+        sp<ICameraDeviceSession> *session /*out*/,
+        camera_metadata_t **staticMeta /*out*/) {
+    ASSERT_NE(nullptr, env);
+    ASSERT_NE(nullptr, session);
+    ASSERT_NE(nullptr, staticMeta);
+
+    ::android::sp<ICameraDevice> device3_2;
+    ALOGI("configureStreams: Testing camera device %s", name.c_str());
+    Return<void> ret;
+    ret = env->mProvider->getCameraDeviceInterface_V3_x(
+        name,
+        [&](auto status, const auto& device) {
+            ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                  (int)status);
+            ASSERT_EQ(Status::OK, status);
+            ASSERT_NE(device, nullptr);
+            device3_2 = device;
+        });
+    ASSERT_TRUE(ret.isOk());
+
+    sp<EmptyDeviceCb> cb = new EmptyDeviceCb();
+    ret = device3_2->open(cb, [&](auto status, const auto& newSession) {
+            ALOGI("device::open returns status:%d", (int)status);
+            ASSERT_EQ(Status::OK, status);
+            ASSERT_NE(newSession, nullptr);
+            *session = newSession;
+        });
+    ASSERT_TRUE(ret.isOk());
+
+    ret = device3_2->getCameraCharacteristics([&] (Status s,
+            CameraMetadata metadata) {
+        ASSERT_EQ(Status::OK, s);
+        *staticMeta = clone_camera_metadata(
+                reinterpret_cast<const camera_metadata_t*>(metadata.data()));
+        ASSERT_NE(nullptr, *staticMeta);
+    });
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Open a particular camera device.
+void CameraHidlTest::openCameraDevice(const std::string &name,
+        const CameraHidlEnvironment* env,
+        sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
+    ASSERT_TRUE(nullptr != env);
+    ASSERT_TRUE(nullptr != device1);
+
+    Return<void> ret;
+    ret = env->mProvider->getCameraDeviceInterface_V1_x(
+            name,
+            [&](auto status, const auto& device) {
+            ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                  (int)status);
+            ASSERT_EQ(Status::OK, status);
+            ASSERT_NE(device, nullptr);
+            *device1 = device;
+        });
+    ASSERT_TRUE(ret.isOk());
+
+    sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this);
+    Return<Status> returnStatus = (*device1)->open(deviceCb);
+    ASSERT_TRUE(returnStatus.isOk());
+    ASSERT_EQ(Status::OK, returnStatus);
+}
+
+// Initialize and configure a preview window.
+void CameraHidlTest::setupPreviewWindow(
+        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
+        sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
+        sp<BufferItemHander> *bufferHandler /*out*/) {
+    ASSERT_NE(nullptr, device.get());
+    ASSERT_NE(nullptr, bufferItemConsumer);
+    ASSERT_NE(nullptr, bufferHandler);
+
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer);
+    *bufferItemConsumer = new BufferItemConsumer(consumer,
+            GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
+    ASSERT_NE(nullptr, (*bufferItemConsumer).get());
+    *bufferHandler = new BufferItemHander(*bufferItemConsumer);
+    ASSERT_NE(nullptr, (*bufferHandler).get());
+    (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
+    sp<Surface> surface = new Surface(producer);
+    sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
+
+    auto rc = device->setPreviewWindow(previewCb);
+    ASSERT_TRUE(rc.isOk());
+    ASSERT_EQ(Status::OK, rc);
+}
+
+// Stop camera preview and close camera.
+void CameraHidlTest::stopPreviewAndClose(
+        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
+    Return<void> ret = device->stopPreview();
+    ASSERT_TRUE(ret.isOk());
+
+    ret = device->close();
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Enable a specific camera message type.
+void CameraHidlTest::enableMsgType(unsigned int msgType,
+        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
+    Return<void> ret = device->enableMsgType(msgType);
+    ASSERT_TRUE(ret.isOk());
+
+    Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
+    ASSERT_TRUE(returnBoolStatus.isOk());
+    ASSERT_TRUE(returnBoolStatus);
+}
+
+// Disable a specific camera message type.
+void CameraHidlTest::disableMsgType(unsigned int msgType,
+        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
+    Return<void> ret = device->disableMsgType(msgType);
+    ASSERT_TRUE(ret.isOk());
+
+    Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
+    ASSERT_TRUE(returnBoolStatus.isOk());
+    ASSERT_FALSE(returnBoolStatus);
+}
+
+// Wait until a specific frame notification arrives.
+void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame,
+        std::unique_lock<std::mutex> &l) {
+    while (msgFrame != mDataMessageTypeReceived) {
+        auto timeout = std::chrono::system_clock::now() +
+                std::chrono::seconds(kStreamBufferTimeoutSec);
+        ASSERT_NE(std::cv_status::timeout,
+                mResultCondition.wait_until(l, timeout));
+    }
+}
+
+// Start preview on a particular camera device
+void CameraHidlTest::startPreview(
+        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
+    Return<Status> returnStatus = device->startPreview();
+    ASSERT_TRUE(returnStatus.isOk());
+    ASSERT_EQ(Status::OK, returnStatus);
+}
+
+// Retrieve camera parameters.
+void CameraHidlTest::getParameters(
+        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
+        CameraParameters *cameraParams /*out*/) {
+    ASSERT_NE(nullptr, cameraParams);
+
+    Return<void> ret;
+    ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) {
+        ASSERT_FALSE(params.empty());
+        ::android::String8 paramString(params.c_str());
+        (*cameraParams).unflatten(paramString);
+    });
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Set camera parameters.
+void CameraHidlTest::setParameters(
+        const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
+        const CameraParameters &cameraParams) {
+    Return<Status> returnStatus = device->setParameters(
+            cameraParams.flatten().string());
+    ASSERT_TRUE(returnStatus.isOk());
+    ASSERT_EQ(Status::OK, returnStatus);
+}
+
 int main(int argc, char **argv) {
   ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/configstore/1.0/ISurfaceFlingerConfigs.hal b/configstore/1.0/ISurfaceFlingerConfigs.hal
index 318590d..58cb9f1 100644
--- a/configstore/1.0/ISurfaceFlingerConfigs.hal
+++ b/configstore/1.0/ISurfaceFlingerConfigs.hal
@@ -41,4 +41,39 @@
     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);
+
+    /*
+     * Specify the offset in nanoseconds to add to vsync time when timestamping
+     * present fences.
+     */
+    presentTimeOffsetFromVSyncNs() generates(OptionalInt64 value);
 };
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.cpp b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
index f73ecb4..86e9b35 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
@@ -39,6 +39,46 @@
     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();
+}
+
+Return<void> SurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs(presentTimeOffsetFromVSyncNs_cb _hidl_cb) {
+#ifdef PRESENT_TIME_OFFSET_FROM_VSYNC_NS
+      _hidl_cb({true, PRESENT_TIME_OFFSET_FROM_VSYNC_NS});
+      LOG(INFO) << "SurfaceFlinger presentTimeStampOffsetNs =  " << PRESENT_TIME_OFFSET_FROM_VSYNC_NS;
+#else
+      _hidl_cb({false, 0});
+#endif
+      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..8378383 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.h
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.h
@@ -27,6 +27,10 @@
     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;
+    Return<void> presentTimeOffsetFromVSyncNs(presentTimeOffsetFromVSyncNs_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..d824072 100644
--- a/configstore/1.0/default/surfaceflinger.mk
+++ b/configstore/1.0/default/surfaceflinger.mk
@@ -12,3 +12,25 @@
 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
+
+ifneq ($(PRESENT_TIME_OFFSET_FROM_VSYNC_NS),)
+    LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=$(PRESENT_TIME_OFFSET_FROM_VSYNC_NS)
+else
+    LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=0
+endif
diff --git a/drm/1.0/ICryptoPlugin.hal b/drm/1.0/ICryptoPlugin.hal
index ca8fa50..0a7fd26 100644
--- a/drm/1.0/ICryptoPlugin.hal
+++ b/drm/1.0/ICryptoPlugin.hal
@@ -99,7 +99,8 @@
      * ERROR_DRM_RESOURCE_BUSY if the resources required to perform the
      * decryption are not available, ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION
      * if required output protections are not active,
-     * ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not opened, or
+     * ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not opened,
+     * ERROR_DRM_DECRYPT if the decrypt operation fails, and
      * ERROR_DRM_CANNOT_HANDLE in other failure cases.
      * @return bytesWritten the number of bytes output from the decryption
      * @return detailedError if the error is a vendor-specific error, the
diff --git a/drm/1.0/default/TypeConvert.cpp b/drm/1.0/default/TypeConvert.cpp
index ede2a38..3a262c3 100644
--- a/drm/1.0/default/TypeConvert.cpp
+++ b/drm/1.0/default/TypeConvert.cpp
@@ -59,6 +59,9 @@
     case android::ERROR_DRM_DEVICE_REVOKED:
         status = Status::ERROR_DRM_DEVICE_REVOKED;
         break;
+    case android::ERROR_DRM_DECRYPT:
+        status = Status::ERROR_DRM_DECRYPT;
+        break;
     default:
         ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN",
             legacyStatus);
diff --git a/drm/1.0/types.hal b/drm/1.0/types.hal
index 5273044..cea5b16 100644
--- a/drm/1.0/types.hal
+++ b/drm/1.0/types.hal
@@ -90,6 +90,12 @@
     ERROR_DRM_DEVICE_REVOKED,
 
     /**
+     * The DRM Plugin must return ERROR_DRM_DECRYPT if the CryptoPlugin
+     * decrypt operation fails.
+     */
+    ERROR_DRM_DECRYPT,
+
+    /**
      * ERROR_DRM_UNKNOWN must be returned when a fatal failure occurs and no
      * other defined error is appropriate.
      */
diff --git a/graphics/Android.bp b/graphics/Android.bp
index eaa47ae..f4f7db4 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -3,6 +3,7 @@
     "allocator/2.0",
     "allocator/2.0/default",
     "allocator/2.0/vts/functional",
+    "bufferqueue/1.0",
     "common/1.0",
     "composer/2.1",
     "composer/2.1/default",
diff --git a/graphics/bufferqueue/1.0/Android.bp b/graphics/bufferqueue/1.0/Android.bp
new file mode 100644
index 0000000..4ba764f
--- /dev/null
+++ b/graphics/bufferqueue/1.0/Android.bp
@@ -0,0 +1,70 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.graphics.bufferqueue@1.0_hal",
+    srcs: [
+        "IGraphicBufferProducer.hal",
+        "IProducerListener.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.graphics.bufferqueue@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.graphics.bufferqueue@1.0",
+    srcs: [
+        ":android.hardware.graphics.bufferqueue@1.0_hal",
+    ],
+    out: [
+        "android/hardware/graphics/bufferqueue/1.0/GraphicBufferProducerAll.cpp",
+        "android/hardware/graphics/bufferqueue/1.0/ProducerListenerAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.graphics.bufferqueue@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.graphics.bufferqueue@1.0",
+    srcs: [
+        ":android.hardware.graphics.bufferqueue@1.0_hal",
+    ],
+    out: [
+        "android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h",
+        "android/hardware/graphics/bufferqueue/1.0/IHwGraphicBufferProducer.h",
+        "android/hardware/graphics/bufferqueue/1.0/BnHwGraphicBufferProducer.h",
+        "android/hardware/graphics/bufferqueue/1.0/BpHwGraphicBufferProducer.h",
+        "android/hardware/graphics/bufferqueue/1.0/BsGraphicBufferProducer.h",
+        "android/hardware/graphics/bufferqueue/1.0/IProducerListener.h",
+        "android/hardware/graphics/bufferqueue/1.0/IHwProducerListener.h",
+        "android/hardware/graphics/bufferqueue/1.0/BnHwProducerListener.h",
+        "android/hardware/graphics/bufferqueue/1.0/BpHwProducerListener.h",
+        "android/hardware/graphics/bufferqueue/1.0/BsProducerListener.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.graphics.bufferqueue@1.0",
+    generated_sources: ["android.hardware.graphics.bufferqueue@1.0_genc++"],
+    generated_headers: ["android.hardware.graphics.bufferqueue@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.graphics.bufferqueue@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.graphics.common@1.0",
+        "android.hardware.media@1.0",
+        "android.hidl.base@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.graphics.common@1.0",
+        "android.hardware.media@1.0",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/media/omx/1.0/IOmxBufferProducer.hal b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
similarity index 95%
rename from media/omx/1.0/IOmxBufferProducer.hal
rename to graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
index 7e2172b..c59a16c 100644
--- a/media/omx/1.0/IOmxBufferProducer.hal
+++ b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
@@ -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.
@@ -14,20 +14,29 @@
  * limitations under the License.
  */
 
-package android.hardware.media.omx@1.0;
+package android.hardware.graphics.bufferqueue@1.0;
+
+import android.hardware.media@1.0::Fence;
+import android.hardware.media@1.0::AnwBuffer;
+import android.hardware.media@1.0::Rect;
+import android.hardware.media@1.0::Region;
 
 import android.hardware.graphics.common@1.0::Dataspace;
 import android.hardware.graphics.common@1.0::PixelFormat;
 
-import android.hardware.media@1.0::types;
-import IOmxProducerListener;
+import IProducerListener;
 
 /**
  * Ref: frameworks/native/include/gui/IGraphicBufferProducer.h:
  *      IGraphicBufferProducer
  * This is a wrapper/wrapped HAL interface for the actual binder interface.
  */
-interface IOmxBufferProducer {
+interface IGraphicBufferProducer {
+
+    /**
+     * Type for return values of functions in IGraphicBufferProducer.
+     */
+    typedef int32_t Status;
 
     /**
      * Ref: frameworks/native/include/ui/FenceTime.h: FenceTime::Snapshot
@@ -142,7 +151,7 @@
 
     /**
      * requestBuffer requests a new buffer for the given index. The server (i.e.
-     * the IOmxBufferProducer implementation) assigns the newly created
+     * the IProducerListener implementation) assigns the newly created
      * buffer to the given slot index, and the client is expected to mirror the
      * slot->buffer mapping so that it's not necessary to transfer an
      * AnwBuffer for every dequeue operation.
@@ -466,12 +475,12 @@
         );
 
     /**
-     * connect attempts to connect a client API to the IOmxBufferProducer.
-     * This must be called before any other IOmxBufferProducer methods are
+     * connect attempts to connect a client API to the IGraphicBufferProducer.
+     * This must be called before any other IGraphicBufferProducer methods are
      * called except for getAllocator. A consumer must be already connected.
      *
      * This method will fail if the connect was previously called on the
-     * IOmxBufferProducer and no corresponding disconnect call was made.
+     * IGraphicBufferProducer and no corresponding disconnect call was made.
      *
      * The listener is an optional binder callback object that can be used if
      * the producer wants to be notified when the consumer releases a buffer
@@ -506,7 +515,7 @@
      * should be treated as opaque fatal unrecoverable errors.
      */
     connect(
-            IOmxProducerListener listener,
+            IProducerListener listener,
             int32_t api,
             bool producerControlledByApp
         ) generates (
@@ -516,8 +525,8 @@
 
     /**
      * disconnect attempts to disconnect a client API from the
-     * IOmxBufferProducer.  Calling this method will cause any subsequent
-     * calls to other IOmxBufferProducer methods to fail except for
+     * IGraphicBufferProducer.  Calling this method will cause any subsequent
+     * calls to other IGraphicBufferProducer methods to fail except for
      * getAllocator and connect.  Successfully calling connect after this will
      * allow the other methods to succeed again.
      *
@@ -526,7 +535,7 @@
      * Alternatively if mode is AllLocal, then the API value is ignored, and any API
      * connected from the same PID calling disconnect will be disconnected.
      *
-     * Disconnecting from an abandoned IOmxBufferProducer is legal and
+     * Disconnecting from an abandoned IGraphicBufferProducer is legal and
      * is considered a no-op.
      *
      * Return of a value other than NO_ERROR means an error has occurred:
@@ -543,7 +552,7 @@
         );
 
     /**
-     * Attaches a sideband buffer stream to the IOmxBufferProducer.
+     * Attaches a sideband buffer stream to the IGraphicBufferProducer.
      *
      * A sideband stream is a device-specific mechanism for passing buffers
      * from the producer to the consumer without using dequeueBuffer/
diff --git a/media/omx/1.0/IOmxProducerListener.hal b/graphics/bufferqueue/1.0/IProducerListener.hal
similarity index 91%
rename from media/omx/1.0/IOmxProducerListener.hal
rename to graphics/bufferqueue/1.0/IProducerListener.hal
index 7fde93b..206a500 100644
--- a/media/omx/1.0/IOmxProducerListener.hal
+++ b/graphics/bufferqueue/1.0/IProducerListener.hal
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-package android.hardware.media.omx@1.0;
+package android.hardware.graphics.bufferqueue@1.0;
 
 /**
  * Ref: frameworks/native/include/gui/IProducerListener.h: IProducerListener
  * This is a wrapper/wrapped HAL interface for the actual binder interface.
  */
-interface IOmxProducerListener {
+interface IProducerListener {
     oneway onBufferReleased();
     needsReleaseNotify() generates (bool result);
 };
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/media/omx/1.0/Android.bp b/media/omx/1.0/Android.bp
index 85d15ae..81dd617 100644
--- a/media/omx/1.0/Android.bp
+++ b/media/omx/1.0/Android.bp
@@ -6,11 +6,9 @@
         "types.hal",
         "IGraphicBufferSource.hal",
         "IOmx.hal",
-        "IOmxBufferProducer.hal",
         "IOmxBufferSource.hal",
         "IOmxNode.hal",
         "IOmxObserver.hal",
-        "IOmxProducerListener.hal",
     ],
 }
 
@@ -25,11 +23,9 @@
         "android/hardware/media/omx/1.0/types.cpp",
         "android/hardware/media/omx/1.0/GraphicBufferSourceAll.cpp",
         "android/hardware/media/omx/1.0/OmxAll.cpp",
-        "android/hardware/media/omx/1.0/OmxBufferProducerAll.cpp",
         "android/hardware/media/omx/1.0/OmxBufferSourceAll.cpp",
         "android/hardware/media/omx/1.0/OmxNodeAll.cpp",
         "android/hardware/media/omx/1.0/OmxObserverAll.cpp",
-        "android/hardware/media/omx/1.0/OmxProducerListenerAll.cpp",
     ],
 }
 
@@ -52,11 +48,6 @@
         "android/hardware/media/omx/1.0/BnHwOmx.h",
         "android/hardware/media/omx/1.0/BpHwOmx.h",
         "android/hardware/media/omx/1.0/BsOmx.h",
-        "android/hardware/media/omx/1.0/IOmxBufferProducer.h",
-        "android/hardware/media/omx/1.0/IHwOmxBufferProducer.h",
-        "android/hardware/media/omx/1.0/BnHwOmxBufferProducer.h",
-        "android/hardware/media/omx/1.0/BpHwOmxBufferProducer.h",
-        "android/hardware/media/omx/1.0/BsOmxBufferProducer.h",
         "android/hardware/media/omx/1.0/IOmxBufferSource.h",
         "android/hardware/media/omx/1.0/IHwOmxBufferSource.h",
         "android/hardware/media/omx/1.0/BnHwOmxBufferSource.h",
@@ -72,11 +63,6 @@
         "android/hardware/media/omx/1.0/BnHwOmxObserver.h",
         "android/hardware/media/omx/1.0/BpHwOmxObserver.h",
         "android/hardware/media/omx/1.0/BsOmxObserver.h",
-        "android/hardware/media/omx/1.0/IOmxProducerListener.h",
-        "android/hardware/media/omx/1.0/IHwOmxProducerListener.h",
-        "android/hardware/media/omx/1.0/BnHwOmxProducerListener.h",
-        "android/hardware/media/omx/1.0/BpHwOmxProducerListener.h",
-        "android/hardware/media/omx/1.0/BsOmxProducerListener.h",
     ],
 }
 
@@ -92,6 +78,7 @@
         "liblog",
         "libutils",
         "libcutils",
+        "android.hardware.graphics.bufferqueue@1.0",
         "android.hardware.graphics.common@1.0",
         "android.hardware.media@1.0",
         "android.hidl.base@1.0",
@@ -101,6 +88,7 @@
         "libhidltransport",
         "libhwbinder",
         "libutils",
+        "android.hardware.graphics.bufferqueue@1.0",
         "android.hardware.graphics.common@1.0",
         "android.hardware.media@1.0",
         "android.hidl.base@1.0",
diff --git a/media/omx/1.0/IOmx.hal b/media/omx/1.0/IOmx.hal
index acb1aae..78d4b32 100644
--- a/media/omx/1.0/IOmx.hal
+++ b/media/omx/1.0/IOmx.hal
@@ -16,11 +16,11 @@
 
 package android.hardware.media.omx@1.0;
 
+import android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer;
 import android.hardware.media@1.0::types;
 
 import IOmxNode;
 import IOmxObserver;
-import IOmxBufferProducer;
 import IGraphicBufferSource;
 
 /**
@@ -76,7 +76,7 @@
     createInputSurface(
         ) generates (
             Status status,
-            IOmxBufferProducer producer,
+            IGraphicBufferProducer producer,
             IGraphicBufferSource source
         );
 };
diff --git a/radio/1.0/IRadio.hal b/radio/1.0/IRadio.hal
index b3e3e98..0b1bf40 100644
--- a/radio/1.0/IRadio.hal
+++ b/radio/1.0/IRadio.hal
@@ -630,7 +630,6 @@
 
     /*
      * Scans for available networks
-     * This request must not respond until the new operator is selected and registered.
      *
      * @param serial Serial number of request.
      *
diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal
index cd0899a..bf50792 100644
--- a/radio/1.0/IRadioResponse.hal
+++ b/radio/1.0/IRadioResponse.hal
@@ -787,10 +787,13 @@
      *
      * Valid errors returned:
      *   RadioError:NONE
-     *   RadioError:INVALID_ARGUMENTS
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:OPERATION_NOT_ALLOWED
-     *   RadioError:GENERIC_FAILURE
+     *   RadioError:ABORTED
+     *   RadioError:DEVICE_IN_USE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:MODEM_ERR
      */
     oneway getAvailableNetworksResponse(RadioResponseInfo info,
             vec<OperatorInfo> networkInfos);
diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal
index 7c1d143..9b904a5 100644
--- a/radio/1.0/types.hal
+++ b/radio/1.0/types.hal
@@ -86,9 +86,11 @@
     SS_MODIFIED_TO_SS = 27,               // SS request modified to different SS request
     LCE_NOT_SUPPORTED = 36,               // LCE service not supported(36 in RILConstants.java)
     NO_MEMORY = 37,                       // Not sufficient memory to process the request
-    INTERNAL_ERR = 38,                    // Hit unexpected vendor internal error scenario
+    INTERNAL_ERR = 38,                    // Modem hit unexpected error scenario while handling
+                                          // this request
     SYSTEM_ERR = 39,                      // Hit platform or system error
-    MODEM_ERR = 40,                       // Hit unexpected modem error
+    MODEM_ERR = 40,                       // Vendor RIL got unexpected or incorrect response
+                                          // from modem for this request
     INVALID_STATE = 41,                   // Unexpected request for the current state
     NO_RESOURCES = 42,                    // Not sufficient resource to process the request
     SIM_ERR = 43,                         // Received error from SIM card
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index 1298e16..d21b512 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -20,6 +20,7 @@
 #include <android/hardware/sensors/1.0/types.h>
 #include <android/log.h>
 #include <cutils/ashmem.h>
+#include <utils/SystemClock.h>
 #include <VtsHalHidlTargetTestBase.h>
 #include <hardware/sensors.h>       // for sensor type strings
 
@@ -42,6 +43,7 @@
 using namespace ::android::hardware::sensors::V1_0;
 
 // Test environment for sensors
+class SensorsHidlTest;
 class SensorsHidlEnvironment : public ::testing::Environment {
  public:
   // get the test environment singleton
@@ -50,9 +52,6 @@
     return instance;
   }
 
-  // sensors hidl service
-  sp<ISensors> sensors;
-
   virtual void SetUp();
   virtual void TearDown();
 
@@ -64,10 +63,15 @@
   void setCollection(bool enable);
 
  private:
+  friend SensorsHidlTest;
+  // sensors hidl service
+  sp<ISensors> sensors;
+
   SensorsHidlEnvironment() {}
 
   void addEvent(const Event& ev);
   void startPollingThread();
+  void resetHal();
   static void pollingThread(SensorsHidlEnvironment* env, std::shared_ptr<bool> stop);
 
   bool collectionEnabled;
@@ -80,9 +84,9 @@
 };
 
 void SensorsHidlEnvironment::SetUp() {
-  sensors = ::testing::VtsHalHidlTargetTestBase::getService<ISensors>();
-  ALOGI_IF(sensors, "sensors is not nullptr, %p", sensors.get());
-  ASSERT_NE(sensors, nullptr);
+  resetHal();
+
+  ASSERT_NE(sensors, nullptr) << "sensors is nullptr, cannot get hidl service";
 
   collectionEnabled = false;
   startPollingThread();
@@ -93,14 +97,77 @@
 }
 
 void SensorsHidlEnvironment::TearDown() {
-  ALOGI("TearDown SensorsHidlEnvironement");
-
   if (stopThread) {
     *stopThread = true;
   }
   pollThread.detach();
 }
 
+void SensorsHidlEnvironment::resetHal() {
+  // wait upto 100ms * 10 = 1s for hidl service.
+  constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
+
+  std::string step;
+  bool succeed = false;
+  for (size_t retry = 10; retry > 0; --retry) {
+    // this do ... while is for easy error handling
+    do {
+      step = "getService()";
+      sensors = ISensors::getService();
+      if (sensors == nullptr) {
+        break;
+      }
+
+      step = "poll() check";
+      // Poke ISensor service. If it has lingering connection from previous generation of
+      // system server, it will kill itself. There is no intention to handle the poll result,
+      // which will be done since the size is 0.
+      if(!sensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
+        break;
+      }
+
+      step = "getSensorList";
+      std::vector<SensorInfo> sensorList;
+      if (!sensors->getSensorsList(
+          [&] (const ::android::hardware::hidl_vec<SensorInfo> &list) {
+            sensorList.reserve(list.size());
+            for (size_t i = 0; i < list.size(); ++i) {
+              sensorList.push_back(list[i]);
+            }
+          }).isOk()) {
+        break;
+      }
+
+      // stop each sensor individually
+      step = "stop each sensor";
+      bool ok = true;
+      for (const auto &i : sensorList) {
+        if (!sensors->activate(i.sensorHandle, false).isOk()) {
+          ok = false;
+          break;
+        }
+      }
+      if (!ok) {
+        break;
+      }
+
+      // mark it done
+      step = "done";
+      succeed = true;
+    } while(0);
+
+    if (succeed) {
+      return;
+    }
+
+    // Delay 100ms before retry, hidl service is expected to come up in short time after crash.
+    ALOGI("%s unsuccessful, try again soon (remaining retry %zu).", step.c_str(), retry - 1);
+    std::this_thread::sleep_for(RETRY_DELAY);
+  }
+
+  sensors = nullptr;
+}
+
 void SensorsHidlEnvironment::catEvents(std::vector<Event>* output) {
   std::lock_guard<std::mutex> lock(events_mutex);
   if (output) {
@@ -257,6 +324,10 @@
       }
       break;
     }
+    case SharedMemType::GRALLOC: {
+
+      break;
+    }
     default:
       break;
   }
@@ -308,6 +379,58 @@
   return m;
 }
 
+class SensorEventsChecker {
+ public:
+  virtual bool check(const std::vector<Event> &events, std::string *out) const = 0;
+  virtual ~SensorEventsChecker() {}
+};
+
+class NullChecker : public SensorEventsChecker {
+ public:
+  virtual bool check(const std::vector<Event> &, std::string *) const {
+    return true;
+  }
+};
+
+class SensorEventPerEventChecker : public SensorEventsChecker {
+ public:
+  virtual bool checkEvent(const Event &event, std::string *out) const = 0;
+  virtual bool check(const std::vector<Event> &events, std::string *out) const {
+    for (const auto &e : events) {
+      if (!checkEvent(e, out)) {
+        return false;
+      }
+    }
+    return true;
+  }
+};
+
+class Vec3NormChecker : public SensorEventPerEventChecker {
+ public:
+  Vec3NormChecker(float min, float max) : mRange(min, max) {}
+  static Vec3NormChecker byNominal(float nominal, float allowedError) {
+    return Vec3NormChecker(nominal - allowedError, nominal + allowedError);
+  }
+
+  virtual bool checkEvent(const Event &event, std::string *out) const {
+    Vec3 v = event.u.vec3;
+    float norm = std::sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
+    if (norm < mRange.first || norm > mRange.second) {
+      if (out != nullptr) {
+        std::ostringstream ss;
+        ss << "Event @ " << event.timestamp << " (" << v.x << ", " << v.y << ", " << v.z << ")"
+           << " has norm " << norm << ", which is beyond range"
+           << " [" << mRange.first << ", " << mRange.second << "]";
+        *out = ss.str();
+      }
+      return false;
+    }
+    return true;
+  }
+ protected:
+  std::pair<float, float> mRange;
+};
+
 // The main test class for SENSORS HIDL HAL.
 class SensorsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
  public:
@@ -332,6 +455,7 @@
 
  protected:
   SensorInfo defaultSensorByType(SensorType type);
+  std::vector<SensorInfo> getSensorsList();
   std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
         bool clearBeforeStart = true, bool changeCollection = true);
 
@@ -393,16 +517,36 @@
     return (int32_t) type > 0;
   }
 
-  static bool typeMatchStringType(SensorType type, const hidl_string& stringType);
-  static bool typeMatchReportMode(SensorType type, SensorFlagBits reportMode);
-  static bool delayMatchReportMode(int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode);
+  void testStreamingOperation(SensorType type,
+                              std::chrono::nanoseconds samplingPeriod,
+                              std::chrono::seconds duration,
+                              const SensorEventsChecker &checker);
+  void testSamplingRateHotSwitchOperation(SensorType type);
+  void testBatchingOperation(SensorType type);
+  void testDirectReportOperation(
+      SensorType type, SharedMemType memType, RateLevel rate, const SensorEventsChecker &checker);
+
+  static void assertTypeMatchStringType(SensorType type, const hidl_string& stringType);
+  static void assertTypeMatchReportMode(SensorType type, SensorFlagBits reportMode);
+  static void assertDelayMatchReportMode(
+          int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode);
   static SensorFlagBits expectedReportModeForType(SensorType type);
+  static bool isDirectReportRateSupported(SensorInfo sensor, RateLevel rate);
+  static bool isDirectChannelTypeSupported(SensorInfo sensor, SharedMemType type);
+
+  // checkers
+  static const Vec3NormChecker sAccelNormChecker;
+  static const Vec3NormChecker sGyroNormChecker;
 
   // all sensors and direct channnels used
   std::unordered_set<int32_t> mSensorHandles;
   std::unordered_set<int32_t> mDirectChannelHandles;
 };
 
+const Vec3NormChecker SensorsHidlTest::sAccelNormChecker(
+        Vec3NormChecker::byNominal(GRAVITY_EARTH, 0.5f/*m/s^2*/));
+const Vec3NormChecker SensorsHidlTest::sGyroNormChecker(
+        Vec3NormChecker::byNominal(0.f, 0.1f/*rad/s*/));
 
 Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
   // If activating a sensor, add the handle in a set so that when test fails it can be turned off.
@@ -433,7 +577,7 @@
 std::vector<Event> SensorsHidlTest::collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
       bool clearBeforeStart, bool changeCollection) {
   std::vector<Event> events;
-  constexpr useconds_t SLEEP_GRANULARITY = 100*1000; //gradularity 100 ms
+  constexpr useconds_t SLEEP_GRANULARITY = 100*1000; //granularity 100 ms
 
   ALOGI("collect max of %zu events for %d us, clearBeforeStart %d",
         nEventLimit, timeLimitUs, clearBeforeStart);
@@ -464,94 +608,93 @@
   return events;
 }
 
-bool SensorsHidlTest::typeMatchStringType(SensorType type, const hidl_string& stringType) {
+void SensorsHidlTest::assertTypeMatchStringType(SensorType type, const hidl_string& stringType) {
 
   if (type >= SensorType::DEVICE_PRIVATE_BASE) {
-    return true;
+    return;
   }
 
-  bool res = true;
   switch (type) {
 #define CHECK_TYPE_STRING_FOR_SENSOR_TYPE(type) \
-    case SensorType::type: res = stringType == SENSOR_STRING_TYPE_ ## type;\
-      break;\
-
+    case SensorType::type: ASSERT_STREQ(SENSOR_STRING_TYPE_ ## type, stringType); break;
     CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ACCELEROMETER);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ORIENTATION);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LIGHT);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PRESSURE);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TEMPERATURE);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PROXIMITY);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GRAVITY);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LINEAR_ACCELERATION);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ROTATION_VECTOR);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(RELATIVE_HUMIDITY);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ACCELEROMETER_UNCALIBRATED);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ADDITIONAL_INFO);
     CHECK_TYPE_STRING_FOR_SENSOR_TYPE(AMBIENT_TEMPERATURE);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD_UNCALIBRATED);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DEVICE_ORIENTATION);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DYNAMIC_SENSOR_META);
     CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GAME_ROTATION_VECTOR);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE_UNCALIBRATED);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(SIGNIFICANT_MOTION);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_DETECTOR);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_COUNTER);
     CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GEOMAGNETIC_ROTATION_VECTOR);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GLANCE_GESTURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GRAVITY);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE_UNCALIBRATED);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_BEAT);
     CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_RATE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LIGHT);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LINEAR_ACCELERATION);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LOW_LATENCY_OFFBODY_DETECT);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD_UNCALIBRATED);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MOTION_DETECT);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ORIENTATION);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PICK_UP_GESTURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(POSE_6DOF);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PRESSURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PROXIMITY);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(RELATIVE_HUMIDITY);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ROTATION_VECTOR);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(SIGNIFICANT_MOTION);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STATIONARY_DETECT);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_COUNTER);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_DETECTOR);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TEMPERATURE);
     CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TILT_DETECTOR);
     CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WAKE_GESTURE);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GLANCE_GESTURE);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PICK_UP_GESTURE);
     CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WRIST_TILT_GESTURE);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DEVICE_ORIENTATION);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(POSE_6DOF);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STATIONARY_DETECT);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MOTION_DETECT);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_BEAT);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DYNAMIC_SENSOR_META);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ADDITIONAL_INFO);
-    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LOW_LATENCY_OFFBODY_DETECT);
     default:
-      ALOGW("Type %d is not checked, stringType = %s", (int)type, stringType.c_str());
+      FAIL() << "Type " << static_cast<int>(type) << " in android defined range is not checked, "
+             << "stringType = " << stringType;
 #undef CHECK_TYPE_STRING_FOR_SENSOR_TYPE
   }
-  return res;
 }
 
-bool SensorsHidlTest::typeMatchReportMode(SensorType type, SensorFlagBits reportMode) {
+void SensorsHidlTest::assertTypeMatchReportMode(SensorType type, SensorFlagBits reportMode) {
   if (type >= SensorType::DEVICE_PRIVATE_BASE) {
-    return true;
+    return;
   }
 
   SensorFlagBits expected = expectedReportModeForType(type);
 
-  return expected == (SensorFlagBits)-1 || expected == reportMode;
+  ASSERT_TRUE(expected == (SensorFlagBits) -1 || expected == reportMode)
+      << "reportMode=" << static_cast<int>(reportMode)
+      << "expected=" << static_cast<int>(expected);
 }
 
-bool SensorsHidlTest::delayMatchReportMode(
+void SensorsHidlTest::assertDelayMatchReportMode(
     int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode) {
-  bool res = true;
   switch(reportMode) {
     case SensorFlagBits::CONTINUOUS_MODE:
-      res = (minDelay > 0) && (maxDelay >= 0);
+      ASSERT_LT(0, minDelay);
+      ASSERT_LE(0, maxDelay);
       break;
     case SensorFlagBits::ON_CHANGE_MODE:
-      //TODO: current implementation does not satisfy minDelay == 0 on Proximity
-      res = (minDelay >= 0) && (maxDelay >= 0);
-      //res = (minDelay == 0) && (maxDelay >= 0);
+      ASSERT_LE(0, minDelay);
+      ASSERT_LE(0, maxDelay);
       break;
     case SensorFlagBits::ONE_SHOT_MODE:
-      res = (minDelay == -1) && (maxDelay == 0);
+      ASSERT_EQ(-1, minDelay);
+      ASSERT_EQ(0, maxDelay);
       break;
     case SensorFlagBits::SPECIAL_REPORTING_MODE:
-      res = (minDelay == 0) && (maxDelay == 0);
+      // do not enforce anything for special reporting mode
       break;
     default:
-      res = false;
+      FAIL() << "Report mode " << static_cast<int>(reportMode) << " not checked";
   }
-
-  return res;
 }
 
+// return -1 means no expectation for this type
 SensorFlagBits SensorsHidlTest::expectedReportModeForType(SensorType type) {
   switch (type) {
     case SensorType::ACCELEROMETER:
@@ -599,6 +742,24 @@
   }
 }
 
+bool SensorsHidlTest::isDirectReportRateSupported(SensorInfo sensor, RateLevel rate) {
+  unsigned int r =
+      static_cast<unsigned int>(sensor.flags & SensorFlagBits::MASK_DIRECT_REPORT)
+        >> static_cast<unsigned int>(SensorFlagShift::DIRECT_REPORT);
+  return r >= static_cast<unsigned int>(rate);
+}
+
+bool SensorsHidlTest::isDirectChannelTypeSupported(SensorInfo sensor, SharedMemType type) {
+  switch (type) {
+    case SharedMemType::ASHMEM:
+      return (sensor.flags & SensorFlagBits::DIRECT_CHANNEL_ASHMEM) != 0;
+    case SharedMemType::GRALLOC:
+      return (sensor.flags & SensorFlagBits::DIRECT_CHANNEL_GRALLOC) != 0;
+    default:
+      return false;
+  }
+}
+
 SensorInfo SensorsHidlTest::defaultSensorByType(SensorType type) {
   SensorInfo ret;
 
@@ -617,60 +778,142 @@
   return ret;
 }
 
+std::vector<SensorInfo> SensorsHidlTest::getSensorsList() {
+  std::vector<SensorInfo> ret;
+
+  S()->getSensorsList(
+      [&] (const auto &list) {
+        const size_t count = list.size();
+        ret.reserve(list.size());
+        for (size_t i = 0; i < count; ++i) {
+          ret.push_back(list[i]);
+        }
+      });
+
+  return ret;
+}
+
 // Test if sensor list returned is valid
 TEST_F(SensorsHidlTest, SensorListValid) {
   S()->getSensorsList(
       [&] (const auto &list) {
         const size_t count = list.size();
         for (size_t i = 0; i < count; ++i) {
-          auto &s = list[i];
-          ALOGV("\t%zu: handle=%#08x type=%d name=%s",
-                i, s.sensorHandle, (int)s.type, s.name.c_str());
+          const auto &s = list[i];
+          SCOPED_TRACE(::testing::Message() << i << "/" << count << ": "
+                       << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                       << s.sensorHandle << std::dec
+                       << " type=" << static_cast<int>(s.type)
+                       << " name=" << s.name);
 
           // Test non-empty type string
-          ASSERT_FALSE(s.typeAsString.empty());
+          EXPECT_FALSE(s.typeAsString.empty());
 
           // Test defined type matches defined string type
-          ASSERT_TRUE(typeMatchStringType(s.type, s.typeAsString));
+          EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(s.type, s.typeAsString));
 
           // Test if all sensor has name and vendor
-          ASSERT_FALSE(s.name.empty());
-          ASSERT_FALSE(s.vendor.empty());
+          EXPECT_FALSE(s.name.empty());
+          EXPECT_FALSE(s.vendor.empty());
 
           // Test power > 0, maxRange > 0
-          ASSERT_GE(s.power, 0);
-          ASSERT_GT(s.maxRange, 0);
+          EXPECT_LE(0, s.power);
+          EXPECT_LT(0, s.maxRange);
 
           // Info type, should have no sensor
-          ASSERT_FALSE(
+          EXPECT_FALSE(
               s.type == SensorType::ADDITIONAL_INFO
               || s.type == SensorType::META_DATA);
 
           // Test fifoMax >= fifoReserved
-          ALOGV("max reserve = %d, %d", s.fifoMaxEventCount, s.fifoReservedEventCount);
-          ASSERT_GE(s.fifoMaxEventCount, s.fifoReservedEventCount);
+          EXPECT_GE(s.fifoMaxEventCount, s.fifoReservedEventCount)
+              << "max=" << s.fifoMaxEventCount << " reserved=" << s.fifoReservedEventCount;
 
           // Test Reporting mode valid
-          ASSERT_TRUE(typeMatchReportMode(s.type, extractReportMode(s.flags)));
+          EXPECT_NO_FATAL_FAILURE(assertTypeMatchReportMode(s.type, extractReportMode(s.flags)));
 
           // Test min max are in the right order
-          ASSERT_LE(s.minDelay, s.maxDelay);
+          EXPECT_LE(s.minDelay, s.maxDelay);
           // Test min/max delay matches reporting mode
-          ASSERT_TRUE(delayMatchReportMode(s.minDelay, s.maxDelay, extractReportMode(s.flags)));
+          EXPECT_NO_FATAL_FAILURE(
+              assertDelayMatchReportMode(s.minDelay, s.maxDelay, extractReportMode(s.flags)));
         }
       });
 }
 
-// Test if sensor hal can do normal accelerometer streaming properly
-TEST_F(SensorsHidlTest, NormalAccelerometerStreamingOperation) {
+// Test if sensor list returned is valid
+TEST_F(SensorsHidlTest, SetOperationMode) {
+    std::vector<SensorInfo> sensorList = getSensorsList();
 
+    bool needOperationModeSupport =
+        std::any_of(sensorList.begin(), sensorList.end(),
+                    [] (const auto& s) {
+                      return (s.flags & SensorFlagBits::DATA_INJECTION) != 0;
+                    });
+    if (!needOperationModeSupport) {
+      return;
+    }
+
+    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::DATA_INJECTION));
+    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+}
+
+// Test if sensor list returned is valid
+TEST_F(SensorsHidlTest, InjectSensorEventData) {
+    std::vector<SensorInfo> sensorList = getSensorsList();
+    std::vector<SensorInfo> sensorSupportInjection;
+
+    bool needOperationModeSupport =
+        std::any_of(sensorList.begin(), sensorList.end(),
+                    [&sensorSupportInjection] (const auto& s) {
+                      bool ret = (s.flags & SensorFlagBits::DATA_INJECTION) != 0;
+                      if (ret) {
+                        sensorSupportInjection.push_back(s);
+                      }
+                      return ret;
+                    });
+    if (!needOperationModeSupport) {
+      return;
+    }
+
+    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::DATA_INJECTION));
+
+    for (const auto &s : sensorSupportInjection) {
+      switch (s.type) {
+        case SensorType::ACCELEROMETER:
+        case SensorType::GYROSCOPE:
+        case SensorType::MAGNETIC_FIELD: {
+          usleep(100000); // sleep 100ms
+
+          Event dummy;
+          dummy.timestamp = android::elapsedRealtimeNano();
+          dummy.sensorType = s.type;
+          dummy.sensorHandle = s.sensorHandle;
+          Vec3 v = {1, 2, 3, SensorStatus::ACCURACY_HIGH};
+          dummy.u.vec3 = v;
+
+          EXPECT_EQ(Result::OK, S()->injectSensorData(dummy));
+          break;
+        }
+        default:
+          break;
+      }
+    }
+    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+}
+
+void SensorsHidlTest::testStreamingOperation(SensorType type,
+                                             std::chrono::nanoseconds samplingPeriod,
+                                             std::chrono::seconds duration,
+                                             const SensorEventsChecker &checker) {
   std::vector<Event> events;
 
-  constexpr int64_t samplingPeriodInNs = 20ull*1000*1000; // 20ms
-  constexpr int64_t batchingPeriodInNs = 0; // no batching
-  constexpr useconds_t minTimeUs = 5*1000*1000;  // 5 s
-  constexpr size_t minNEvent = 100;  // at lease 100 events
-  constexpr SensorType type = SensorType::ACCELEROMETER;
+  const int64_t samplingPeriodInNs = samplingPeriod.count();
+  const int64_t batchingPeriodInNs = 0; // no batching
+  const useconds_t minTimeUs = std::chrono::microseconds(duration).count();
+  const size_t minNEvent = duration / samplingPeriod;
 
   SensorInfo sensor = defaultSensorByType(type);
 
@@ -679,6 +922,11 @@
     return;
   }
 
+  if (std::chrono::microseconds(sensor.minDelay) > samplingPeriod) {
+    // rate not supported
+    return;
+  }
+
   int32_t handle = sensor.sensorHandle;
 
   ASSERT_EQ(batch(handle, samplingPeriodInNs, batchingPeriodInNs), Result::OK);
@@ -691,90 +939,110 @@
   ASSERT_GT(events.size(), 0u);
 
   size_t nRealEvent = 0;
+  bool handleMismatchReported = false;
+  bool metaSensorTypeErrorReported = false;
   for (auto & e : events) {
     if (e.sensorType == type) {
-
-      ASSERT_EQ(e.sensorHandle, handle);
-
-      Vec3 acc = e.u.vec3;
-
-      double gravityNorm = std::sqrt(acc.x * acc.x + acc.y * acc.y + acc.z * acc.z);
-      ALOGV("Norm = %f", gravityNorm);
-
-      // assert this is earth gravity
-      ASSERT_TRUE(std::fabs(gravityNorm - GRAVITY_EARTH) < 1);
-
+      // avoid generating hundreds of error
+      if (!handleMismatchReported) {
+        EXPECT_EQ(e.sensorHandle, handle)
+            << (handleMismatchReported = true,
+                "Event of the same type must come from the sensor registered");
+      }
       ++ nRealEvent;
     } else {
-      ALOGI("Event type %d, handle %d", (int) e.sensorType, (int) e.sensorHandle);
-      // Only meta types are allowed besides the subscribed sensor
-      ASSERT_TRUE(isMetaSensorType(e.sensorType));
+      // avoid generating hundreds of error
+      if (!metaSensorTypeErrorReported) {
+        EXPECT_TRUE(isMetaSensorType(e.sensorType))
+            << (metaSensorTypeErrorReported = true,
+                "Only meta types are allowed besides the type registered");
+      }
     }
   }
 
-  ASSERT_GE(nRealEvent, minNEvent / 2); // make sure returned events are not all meta
+  std::string s;
+  EXPECT_TRUE(checker.check(events, &s)) << s;
+
+  EXPECT_GE(nRealEvent, minNEvent / 2); // make sure returned events are not all meta
 }
 
-// Test if sensor hal can do gyroscope streaming properly
-TEST_F(SensorsHidlTest, NormalGyroscopeStreamingOperation) {
-  std::vector<Event> events;
-
-  constexpr int64_t samplingPeriodInNs = 10ull*1000*1000; // 10ms
-  constexpr int64_t batchingPeriodInNs = 0; // no batching
-  constexpr useconds_t minTimeUs = 5*1000*1000;  // 5 s
-  constexpr size_t minNEvent = 200;
-  constexpr SensorType type = SensorType::GYROSCOPE;
-
-  SensorInfo sensor = defaultSensorByType(type);
-
-  if (!isValidType(sensor.type)) {
-    // no default sensor of this type
-    return;
-  }
-
-  int32_t handle = sensor.sensorHandle;
-
-  ASSERT_EQ(batch(handle, samplingPeriodInNs, batchingPeriodInNs), Result::OK);
-  ASSERT_EQ(activate(handle, 1), Result::OK);
-  events = collectEvents(minTimeUs, minNEvent, true /*clearBeforeStart*/);
-  ASSERT_EQ(activate(handle, 0), Result::OK);
-
-  ALOGI("Collected %zu samples", events.size());
-
-  ASSERT_GT(events.size(), 0u);
-
-  size_t nRealEvent = 0;
-  for (auto & e : events) {
-    if (e.sensorType == type) {
-
-      ASSERT_EQ(e.sensorHandle, handle);
-
-      Vec3 gyro = e.u.vec3;
-
-      double gyroNorm = std::sqrt(gyro.x * gyro.x + gyro.y * gyro.y + gyro.z * gyro.z);
-      ALOGV("Gyro Norm = %f", gyroNorm);
-
-      // assert not drifting
-      ASSERT_TRUE(gyroNorm < 0.1);  // < ~5 degree/s
-
-      ++ nRealEvent;
-    } else {
-      ALOGI("Event type %d, handle %d", (int) e.sensorType, (int) e.sensorHandle);
-      // Only meta types are allowed besides the subscribed sensor
-      ASSERT_TRUE(isMetaSensorType(e.sensorType));
-    }
-  }
-
-  ASSERT_GE(nRealEvent, minNEvent / 2); // make sure returned events are not all meta
+// Test if sensor hal can do UI speed accelerometer streaming properly
+TEST_F(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
+  testStreamingOperation(SensorType::ACCELEROMETER,
+                         std::chrono::milliseconds(200),
+                         std::chrono::seconds(5),
+                         sAccelNormChecker);
 }
 
-// Test if sensor hal can do accelerometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
+// Test if sensor hal can do normal speed accelerometer streaming properly
+TEST_F(SensorsHidlTest, AccelerometerStreamingOperationNormal) {
+  testStreamingOperation(SensorType::ACCELEROMETER,
+                         std::chrono::milliseconds(20),
+                         std::chrono::seconds(5),
+                         sAccelNormChecker);
+}
+
+// Test if sensor hal can do game speed accelerometer streaming properly
+TEST_F(SensorsHidlTest, AccelerometerStreamingOperationFast) {
+  testStreamingOperation(SensorType::ACCELEROMETER,
+                         std::chrono::milliseconds(5),
+                         std::chrono::seconds(5),
+                         sAccelNormChecker);
+}
+
+// Test if sensor hal can do UI speed gyroscope streaming properly
+TEST_F(SensorsHidlTest, GyroscopeStreamingOperationSlow) {
+  testStreamingOperation(SensorType::GYROSCOPE,
+                         std::chrono::milliseconds(200),
+                         std::chrono::seconds(5),
+                         sGyroNormChecker);
+}
+
+// Test if sensor hal can do normal speed gyroscope streaming properly
+TEST_F(SensorsHidlTest, GyroscopeStreamingOperationNormal) {
+  testStreamingOperation(SensorType::GYROSCOPE,
+                         std::chrono::milliseconds(20),
+                         std::chrono::seconds(5),
+                         sGyroNormChecker);
+}
+
+// Test if sensor hal can do game speed gyroscope streaming properly
+TEST_F(SensorsHidlTest, GyroscopeStreamingOperationFast) {
+  testStreamingOperation(SensorType::GYROSCOPE,
+                         std::chrono::milliseconds(5),
+                         std::chrono::seconds(5),
+                         sGyroNormChecker);
+}
+
+// Test if sensor hal can do UI speed magnetometer streaming properly
+TEST_F(SensorsHidlTest, MagnetometerStreamingOperationSlow) {
+  testStreamingOperation(SensorType::MAGNETIC_FIELD,
+                         std::chrono::milliseconds(200),
+                         std::chrono::seconds(5),
+                         NullChecker());
+}
+
+// Test if sensor hal can do normal speed magnetometer streaming properly
+TEST_F(SensorsHidlTest, MagnetometerStreamingOperationNormal) {
+  testStreamingOperation(SensorType::MAGNETIC_FIELD,
+                         std::chrono::milliseconds(20),
+                         std::chrono::seconds(5),
+                         NullChecker());
+}
+
+// Test if sensor hal can do game speed magnetometer streaming properly
+TEST_F(SensorsHidlTest, MagnetometerStreamingOperationFast) {
+  testStreamingOperation(SensorType::MAGNETIC_FIELD,
+                         std::chrono::milliseconds(5),
+                         std::chrono::seconds(5),
+                         NullChecker());
+}
+
+void SensorsHidlTest::testSamplingRateHotSwitchOperation(SensorType type) {
   std::vector<Event> events1, events2;
 
   constexpr int64_t batchingPeriodInNs = 0; // no batching
   constexpr size_t minNEvent = 50;
-  constexpr SensorType type = SensorType::ACCELEROMETER;
 
   SensorInfo sensor = defaultSensorByType(type);
 
@@ -845,21 +1113,34 @@
   maxDelayAverageInterval = timestampInterval / (nEvent - 1);
 
   // change of rate is significant.
-  ASSERT_GT((maxDelayAverageInterval - minDelayAverageInterval), minDelayAverageInterval / 10);
+  EXPECT_GT((maxDelayAverageInterval - minDelayAverageInterval), minDelayAverageInterval / 10);
 
   // fastest rate sampling time is close to spec
   ALOGI("minDelayAverageInterval = %" PRId64, minDelayAverageInterval);
-  ASSERT_LT(std::abs(minDelayAverageInterval - minSamplingPeriodInNs),
+  EXPECT_LT(std::abs(minDelayAverageInterval - minSamplingPeriodInNs),
       minSamplingPeriodInNs / 10);
 }
 
-// Test if sensor hal can do normal accelerometer batching properly
-TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
+// Test if sensor hal can do accelerometer sampling rate switch properly when sensor is active
+TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
+  testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER);
+}
+
+// Test if sensor hal can do gyroscope sampling rate switch properly when sensor is active
+TEST_F(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
+  testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE);
+}
+
+// Test if sensor hal can do magnetometer sampling rate switch properly when sensor is active
+TEST_F(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
+  testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD);
+}
+
+void SensorsHidlTest::testBatchingOperation(SensorType type) {
   std::vector<Event> events;
 
-  constexpr int64_t oneSecondInNs = 1ull * 1000 * 1000 * 1000;
-  constexpr SensorType type = SensorType::ACCELEROMETER;
   constexpr int64_t maxBatchingTestTimeNs = 30ull * 1000 * 1000 * 1000;
+  constexpr int64_t oneSecondInNs = 1ull * 1000 * 1000 * 1000;
 
   SensorInfo sensor = defaultSensorByType(type);
 
@@ -922,24 +1203,46 @@
   ASSERT_GT(nEvent, (size_t)(batchingPeriodInNs / minSamplingPeriodInNs * 9 / 10));
 }
 
-// Test sensor event direct report with ashmem for gyro sensor
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReport) {
+// Test if sensor hal can do accelerometer batching properly
+TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
+  testBatchingOperation(SensorType::ACCELEROMETER);
+}
 
-  constexpr SensorType type = SensorType::GYROSCOPE;
-  constexpr size_t kEventSize = 104;
+// Test if sensor hal can do gyroscope batching properly
+TEST_F(SensorsHidlTest, GyroscopeBatchingOperation) {
+  testBatchingOperation(SensorType::GYROSCOPE);
+}
+
+// Test if sensor hal can do magnetometer batching properly
+TEST_F(SensorsHidlTest, MagnetometerBatchingOperation) {
+  testBatchingOperation(SensorType::MAGNETIC_FIELD);
+}
+
+void SensorsHidlTest::testDirectReportOperation(
+    SensorType type, SharedMemType memType, RateLevel rate, const SensorEventsChecker &checker) {
+  constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
   constexpr size_t kNEvent = 500;
   constexpr size_t kMemSize = kEventSize * kNEvent;
 
+  constexpr float kNormalNominal = 50;
+  constexpr float kFastNominal = 200;
+  constexpr float kVeryFastNominal = 800;
+
+  constexpr float kNominalTestTimeSec = 1.f;
+  constexpr float kMaxTestTimeSec = kNominalTestTimeSec + 0.5f; // 0.5 second for initialization
+
   SensorInfo sensor = defaultSensorByType(type);
 
-  if (!(sensor.flags | SensorFlagBits::MASK_DIRECT_REPORT)
-      || !(sensor.flags | SensorFlagBits::DIRECT_CHANNEL_ASHMEM)) {
-    // does not declare support
+  if (!isDirectReportRateSupported(sensor, rate)) {
+    return;
+  }
+
+  if (!isDirectChannelTypeSupported(sensor, memType)) {
     return;
   }
 
   std::unique_ptr<SensorsTestSharedMemory>
-      mem(SensorsTestSharedMemory::create(SharedMemType::ASHMEM, kMemSize));
+      mem(SensorsTestSharedMemory::create(memType, kMemSize));
   ASSERT_NE(mem, nullptr);
 
   char* buffer = mem->getBuffer();
@@ -961,39 +1264,119 @@
   }
 
   int32_t eventToken;
-  configDirectReport(sensor.sensorHandle, channelHandle, RateLevel::NORMAL,
+  configDirectReport(sensor.sensorHandle, channelHandle, rate,
       [&eventToken] (auto result, auto token) {
           ASSERT_EQ(result, Result::OK);
           eventToken = token;
       });
 
-  usleep(1500000); // sleep 1 sec for data, plus 0.5 sec for initialization
+  usleep(static_cast<useconds_t>(kMaxTestTimeSec * 1e6f));
   auto events = mem->parseEvents();
 
-  // allowed to be 55% of nominal freq (50Hz)
-  ASSERT_GT(events.size(), 50u / 2u);
-  ASSERT_LT(events.size(), static_cast<size_t>(110*1.5));
+  // find norminal rate
+  float nominalFreq = 0.f;
+  switch (rate) {
+      case RateLevel::NORMAL:
+          nominalFreq = kNormalNominal;
+          break;
+      case RateLevel::FAST:
+          nominalFreq = kFastNominal;
+          break;
+      case RateLevel::VERY_FAST:
+          nominalFreq = kVeryFastNominal;
+          break;
+      case RateLevel::STOP:
+          FAIL();
+  }
+
+  // allowed to be between 55% and 220% of nominal freq
+  ASSERT_GT(events.size(), static_cast<size_t>(nominalFreq * 0.55f * kNominalTestTimeSec));
+  ASSERT_LT(events.size(), static_cast<size_t>(nominalFreq * 2.2f * kMaxTestTimeSec));
 
   int64_t lastTimestamp = 0;
+  bool typeErrorReported = false;
+  bool tokenErrorReported = false;
+  bool timestampErrorReported = false;
   for (auto &e : events) {
-    ASSERT_EQ(e.sensorType, type);
-    ASSERT_EQ(e.sensorHandle, eventToken);
-    ASSERT_GT(e.timestamp, lastTimestamp);
-
-    Vec3 gyro = e.u.vec3;
-    double gyroNorm = std::sqrt(gyro.x * gyro.x + gyro.y * gyro.y + gyro.z * gyro.z);
-    // assert not drifting
-    ASSERT_TRUE(gyroNorm < 0.1);  // < ~5 degree/sa
-
+    if (!typeErrorReported) {
+      EXPECT_EQ(type, e.sensorType)
+          << (typeErrorReported = true, "Type in event does not match type of sensor registered.");
+    }
+    if (!tokenErrorReported) {
+      EXPECT_EQ(eventToken, e.sensorHandle)
+          << (tokenErrorReported = true,
+            "Event token does not match that retured from configDirectReport");
+    }
+    if (!timestampErrorReported) {
+      EXPECT_GT(e.timestamp, lastTimestamp)
+          << (timestampErrorReported = true, "Timestamp not monotonically increasing");
+    }
     lastTimestamp = e.timestamp;
   }
 
+  std::string s;
+  EXPECT_TRUE(checker.check(events, &s)) << s;
+
   // stop sensor and unregister channel
   configDirectReport(sensor.sensorHandle, channelHandle, RateLevel::STOP,
         [&eventToken] (auto result, auto) {
-            ASSERT_EQ(result, Result::OK);
+            EXPECT_EQ(result, Result::OK);
         });
-  ASSERT_EQ(unregisterDirectChannel(channelHandle), Result::OK);
+  EXPECT_EQ(unregisterDirectChannel(channelHandle), Result::OK);
+}
+
+// Test sensor event direct report with ashmem for accel sensor at normal rate
+TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
+  testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::NORMAL,
+                            sAccelNormChecker);
+}
+
+// Test sensor event direct report with ashmem for accel sensor at fast rate
+TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationFast) {
+  testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::FAST,
+                            sAccelNormChecker);
+}
+
+// Test sensor event direct report with ashmem for accel sensor at very fast rate
+TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationVeryFast) {
+  testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
+                            sAccelNormChecker);
+}
+
+// Test sensor event direct report with ashmem for gyro sensor at normal rate
+TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationNormal) {
+  testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::NORMAL,
+                            sGyroNormChecker);
+}
+
+// Test sensor event direct report with ashmem for gyro sensor at fast rate
+TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationFast) {
+  testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::FAST,
+                            sGyroNormChecker);
+}
+
+// Test sensor event direct report with ashmem for gyro sensor at very fast rate
+TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationVeryFast) {
+  testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
+                            sGyroNormChecker);
+}
+
+// Test sensor event direct report with ashmem for mag sensor at normal rate
+TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationNormal) {
+  testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::NORMAL,
+                            NullChecker());
+}
+
+// Test sensor event direct report with ashmem for mag sensor at fast rate
+TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationFast) {
+  testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::FAST,
+                            NullChecker());
+}
+
+// Test sensor event direct report with ashmem for mag sensor at very fast rate
+TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationVeryFast) {
+  testDirectReportOperation(
+      SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::VERY_FAST, NullChecker());
 }
 
 int main(int argc, char **argv) {
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",
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
index ab1b6a3..c6ac03c 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
@@ -18,8 +18,33 @@
 
 #include <VtsHalHidlTargetTestBase.h>
 
+#include <android/hardware/wifi/supplicant/1.0/ISupplicant.h>
+
 #include "supplicant_hidl_test_utils.h"
 
+using ::android::sp;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
+
+class SupplicantHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        startSupplicantAndWaitForHidlService();
+        supplicant_ = getSupplicant();
+        ASSERT_NE(supplicant_.get(), nullptr);
+    }
+
+    virtual void TearDown() override { stopSupplicant(); }
+
+   protected:
+    // ISupplicant object used for all tests in this fixture.
+    sp<ISupplicant> supplicant_;
+};
+
 /*
  * Create:
  * Ensures that an instance of the ISupplicant proxy object is
@@ -30,3 +55,131 @@
     EXPECT_NE(nullptr, getSupplicant().get());
     stopSupplicant();
 }
+
+/*
+ * ListInterfaces
+ */
+TEST_F(SupplicantHidlTest, ListInterfaces) {
+    std::vector<ISupplicant::IfaceInfo> ifaces;
+    supplicant_->listInterfaces(
+        [&](const SupplicantStatus& status,
+            const hidl_vec<ISupplicant::IfaceInfo>& hidl_ifaces) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            ifaces = hidl_ifaces;
+        });
+
+    EXPECT_NE(ifaces.end(),
+              std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) {
+                  return iface.type == IfaceType::STA;
+              }));
+    EXPECT_NE(ifaces.end(),
+              std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) {
+                  return iface.type == IfaceType::P2P;
+              }));
+}
+
+/*
+ * GetInterface
+ */
+TEST_F(SupplicantHidlTest, GetInterface) {
+    std::vector<ISupplicant::IfaceInfo> ifaces;
+    supplicant_->listInterfaces(
+        [&](const SupplicantStatus& status,
+            const hidl_vec<ISupplicant::IfaceInfo>& hidl_ifaces) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            ifaces = hidl_ifaces;
+        });
+
+    ASSERT_NE(0u, ifaces.size());
+    supplicant_->getInterface(
+        ifaces[0],
+        [&](const SupplicantStatus& status, const sp<ISupplicantIface>& iface) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_NE(nullptr, iface.get());
+        });
+}
+
+/*
+ * SetDebugParams
+ */
+TEST_F(SupplicantHidlTest, SetDebugParams) {
+    bool show_timestamp = true;
+    bool show_keys = true;
+    ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
+
+    supplicant_->setDebugParams(level,
+                                show_timestamp,  // show timestamps
+                                show_keys,       // show keys
+                                [](const SupplicantStatus& status) {
+                                    EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                              status.code);
+                                });
+}
+
+/*
+ * GetDebugLevel
+ */
+TEST_F(SupplicantHidlTest, GetDebugLevel) {
+    bool show_timestamp = true;
+    bool show_keys = true;
+    ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
+
+    supplicant_->setDebugParams(level,
+                                show_timestamp,  // show timestamps
+                                show_keys,       // show keys
+                                [](const SupplicantStatus& status) {
+                                    EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                              status.code);
+                                });
+    EXPECT_EQ(level, supplicant_->getDebugLevel());
+}
+
+/*
+ * IsDebugShowTimestampEnabled
+ */
+TEST_F(SupplicantHidlTest, IsDebugShowTimestampEnabled) {
+    bool show_timestamp = true;
+    bool show_keys = true;
+    ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
+
+    supplicant_->setDebugParams(level,
+                                show_timestamp,  // show timestamps
+                                show_keys,       // show keys
+                                [](const SupplicantStatus& status) {
+                                    EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                              status.code);
+                                });
+    EXPECT_EQ(show_timestamp, supplicant_->isDebugShowTimestampEnabled());
+}
+
+/*
+ * IsDebugShowKeysEnabled
+ */
+TEST_F(SupplicantHidlTest, IsDebugShowKeysEnabled) {
+    bool show_timestamp = true;
+    bool show_keys = true;
+    ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
+
+    supplicant_->setDebugParams(level,
+                                show_timestamp,  // show timestamps
+                                show_keys,       // show keys
+                                [](const SupplicantStatus& status) {
+                                    EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                              status.code);
+                                });
+    EXPECT_EQ(show_keys, supplicant_->isDebugShowKeysEnabled());
+}
+
+/*
+ * SetConcurrenyPriority
+ */
+TEST_F(SupplicantHidlTest, SetConcurrencyPriority) {
+    supplicant_->setConcurrencyPriority(
+        IfaceType::STA, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    supplicant_->setConcurrencyPriority(
+        IfaceType::P2P, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index fdee0c6..1fcfc8c 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -17,9 +17,9 @@
 #include <android-base/logging.h>
 #include <VtsHalHidlTargetTestBase.h>
 
-#include <hidl/HidlTransportSupport.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <android/hidl/manager/1.0/IServiceNotification.h>
+#include <hidl/HidlTransportSupport.h>
 
 #include <wifi_hal/driver_tool.h>
 #include <wifi_system/interface_tool.h>
@@ -174,7 +174,7 @@
 }
 
 sp<ISupplicant> getSupplicant() {
-    return getService<ISupplicant>(kSupplicantServiceName);
+    return ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>();
 }
 
 sp<ISupplicantStaIface> getSupplicantStaIface() {
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 332b57b..c6cf01f 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -18,8 +18,144 @@
 
 #include <VtsHalHidlTargetTestBase.h>
 
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pIface.h>
+
 #include "supplicant_hidl_test_utils.h"
 
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIfaceCallback;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantNetworkId;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+
+namespace {
+constexpr uint8_t kTestSsidPostfix[] = {'t', 'e', 's', 't'};
+constexpr uint8_t kTestMacAddr[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+constexpr uint8_t kTestPeerMacAddr[] = {0x56, 0x67, 0x55, 0xf4, 0x56, 0x92};
+constexpr char kTestConnectPin[] = "34556665";
+constexpr char kTestGroupIfName[] = "TestGroup";
+constexpr uint32_t kTestConnectGoIntent = 6;
+constexpr uint32_t kTestFindTimeout = 5;
+constexpr SupplicantNetworkId kTestNetworkId = 5;
+constexpr uint32_t kTestChannel = 1;
+constexpr uint32_t kTestOperatingClass = 81;
+constexpr uint32_t kTestFreqRange[] = {2412, 2432};
+constexpr uint32_t kTestExtListenPeriod = 400;
+constexpr uint32_t kTestExtListenInterval = 400;
+}  // namespace
+
+class SupplicantP2pIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        startSupplicantAndWaitForHidlService();
+        EXPECT_TRUE(turnOnExcessiveLogging());
+        p2p_iface_ = getSupplicantP2pIface();
+        ASSERT_NE(p2p_iface_.get(), nullptr);
+
+        memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size());
+        memcpy(peer_mac_addr_.data(), kTestPeerMacAddr, peer_mac_addr_.size());
+    }
+
+    virtual void TearDown() override { stopSupplicant(); }
+
+   protected:
+    // ISupplicantP2pIface object used for all tests in this fixture.
+    sp<ISupplicantP2pIface> p2p_iface_;
+    // MAC address to use for various tests.
+    std::array<uint8_t, 6> mac_addr_;
+    std::array<uint8_t, 6> peer_mac_addr_;
+};
+
+class IfaceCallback : public ISupplicantP2pIfaceCallback {
+    Return<void> onNetworkAdded(uint32_t /* id */) override { return Void(); }
+    Return<void> onNetworkRemoved(uint32_t /* id */) override { return Void(); }
+    Return<void> onDeviceFound(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */,
+        const hidl_array<uint8_t, 8>& /* primaryDeviceType */,
+        const hidl_string& /* deviceName */, uint16_t /* configMethods */,
+        uint8_t /* deviceCapabilities */, uint32_t /* groupCapabilities */,
+        const hidl_array<uint8_t, 8>& /* wfdDeviceInfo */) override {
+        return Void();
+    }
+    Return<void> onDeviceLost(
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */) override {
+        return Void();
+    }
+    Return<void> onFindStopped() override { return Void(); }
+    Return<void> onGoNegotiationRequest(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        ISupplicantP2pIfaceCallback::WpsDevPasswordId /* passwordId */)
+        override {
+        return Void();
+    }
+    Return<void> onGoNegotiationCompleted(
+        ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override {
+        return Void();
+    }
+    Return<void> onGroupFormationSuccess() override { return Void(); }
+    Return<void> onGroupFormationFailure(
+        const hidl_string& /* failureReason */) override {
+        return Void();
+    }
+    Return<void> onGroupStarted(
+        const hidl_string& /* groupIfname */, bool /* isGo */,
+        const hidl_vec<uint8_t>& /* ssid */, uint32_t /* frequency */,
+        const hidl_array<uint8_t, 32>& /* psk */,
+        const hidl_string& /* passphrase */,
+        const hidl_array<uint8_t, 6>& /* goDeviceAddress */,
+        bool /* isPersistent */) override {
+        return Void();
+    }
+    Return<void> onGroupRemoved(const hidl_string& /* groupIfname */,
+                                bool /* isGo */) override {
+        return Void();
+    }
+    Return<void> onInvitationReceived(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        const hidl_array<uint8_t, 6>& /* goDeviceAddress */,
+        const hidl_array<uint8_t, 6>& /* bssid */,
+        uint32_t /* persistentNetworkId */,
+        uint32_t /* operatingFrequency */) override {
+        return Void();
+    }
+    Return<void> onInvitationResult(
+        const hidl_array<uint8_t, 6>& /* bssid */,
+        ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override {
+        return Void();
+    }
+    Return<void> onProvisionDiscoveryCompleted(
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */,
+        bool /* isRequest */,
+        ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode /* status */,
+        uint16_t /* configMethods */,
+        const hidl_string& /* generatedPin */) override {
+        return Void();
+    }
+    Return<void> onServiceDiscoveryResponse(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        uint16_t /* updateIndicator */,
+        const hidl_vec<uint8_t>& /* tlvs */) override {
+        return Void();
+    }
+    Return<void> onStaAuthorized(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */) override {
+        return Void();
+    }
+    Return<void> onStaDeauthorized(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */) override {
+        return Void();
+    }
+};
+
 /*
  * Create:
  * Ensures that an instance of the ISupplicantP2pIface proxy object is
@@ -30,3 +166,248 @@
     EXPECT_NE(nullptr, getSupplicantP2pIface().get());
     stopSupplicant();
 }
+
+/*
+ * RegisterCallback
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, RegisterCallback) {
+    p2p_iface_->registerCallback(
+        new IfaceCallback(), [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * GetDeviceAddress
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, GetDeviceAddress) {
+    p2p_iface_->getDeviceAddress(
+        [](const SupplicantStatus& status,
+           const hidl_array<uint8_t, 6>& /* mac_addr */) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * SetSsidPostfix
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetSsidPostfix) {
+    std::vector<uint8_t> ssid(kTestSsidPostfix,
+                              kTestSsidPostfix + sizeof(kTestSsidPostfix));
+    p2p_iface_->setSsidPostfix(ssid, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * Find
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Find) {
+    p2p_iface_->find(kTestFindTimeout, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * StopFind
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, StopFind) {
+    p2p_iface_->find(kTestFindTimeout, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+
+    p2p_iface_->stopFind([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+
+    p2p_iface_->stopFind([](const SupplicantStatus& status) {
+        EXPECT_NE(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * Flush
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Flush) {
+    p2p_iface_->flush([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * Connect
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Connect) {
+    p2p_iface_->connect(
+        mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
+        kTestConnectPin, false, false, kTestConnectGoIntent,
+        [](const SupplicantStatus& status, const hidl_string& /* pin */) {
+            // This is not going to work with fake values.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        });
+}
+
+/*
+ * CancelConnect
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, CancelConnect) {
+    p2p_iface_->connect(
+        mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
+        kTestConnectPin, false, false, kTestConnectGoIntent,
+        [](const SupplicantStatus& status, const hidl_string& /* pin */) {
+            // This is not going to work with fake values.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        });
+
+    p2p_iface_->cancelConnect([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+    });
+}
+
+/*
+ * ProvisionDiscovery
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, ProvisionDiscovery) {
+    p2p_iface_->provisionDiscovery(
+        mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
+        [](const SupplicantStatus& status) {
+            // This is not going to work with fake values.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        });
+}
+
+/*
+ * AddGroup
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, AddGroup) {
+    p2p_iface_->addGroup(false, kTestNetworkId,
+                         [](const SupplicantStatus& /* status */) {
+                             // TODO: Figure out the initialization sequence for
+                             // this to work.
+                             // EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                             // status.code);
+                         });
+}
+
+/*
+ * Reject
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Reject) {
+    p2p_iface_->reject(mac_addr_, [](const SupplicantStatus& status) {
+        // This is not going to work with fake values.
+        EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+    });
+}
+
+/*
+ * Invite
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Invite) {
+    p2p_iface_->invite(kTestGroupIfName, mac_addr_, peer_mac_addr_,
+                       [](const SupplicantStatus& status) {
+                           // This is not going to work with fake values.
+                           EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN,
+                                     status.code);
+                       });
+}
+
+/*
+ * Reinvoke
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Reinvoke) {
+    p2p_iface_->reinvoke(
+        kTestNetworkId, mac_addr_, [](const SupplicantStatus& status) {
+            // This is not going to work with fake values.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
+                      status.code);
+        });
+}
+
+/*
+ * ConfigureExtListen
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, ConfigureExtListen) {
+    p2p_iface_->configureExtListen(kTestExtListenPeriod, kTestExtListenInterval,
+                                   [](const SupplicantStatus& status) {
+                                       EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                                 status.code);
+                                   });
+}
+
+/*
+ * SetListenChannel
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetListenChannel) {
+    p2p_iface_->setListenChannel(
+        kTestChannel, kTestOperatingClass, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * SetDisallowedFrequencies
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetDisallowedFrequencies) {
+    std::vector<ISupplicantP2pIface::FreqRange> ranges = {
+        {kTestFreqRange[0], kTestFreqRange[1]}};
+    p2p_iface_->setDisallowedFrequencies(
+        ranges, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * GetSsid
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, GetSsid) {
+    std::array<uint8_t, 6> mac_addr;
+    memcpy(mac_addr.data(), kTestMacAddr, mac_addr.size());
+    p2p_iface_->getSsid(mac_addr, [](const SupplicantStatus& status,
+                                     const hidl_vec<uint8_t>& /* ssid */) {
+        // This is not going to work with fake values.
+        EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+    });
+}
+
+/*
+ * GetGroupCapability
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, GetGroupCapability) {
+    std::array<uint8_t, 6> mac_addr;
+    memcpy(mac_addr.data(), kTestMacAddr, mac_addr.size());
+    p2p_iface_->getGroupCapability(
+        mac_addr, [](const SupplicantStatus& status, uint32_t /* caps */) {
+            // This is not going to work with fake values.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        });
+}
+
+/*
+ * FlushServices
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, FlushServices) {
+    p2p_iface_->flushServices([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * SetMiracastMode
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetMiracastMode) {
+    p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::DISABLED,
+                                [](const SupplicantStatus& status) {
+                                    EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                              status.code);
+                                });
+    p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::SOURCE,
+                                [](const SupplicantStatus& status) {
+                                    EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                              status.code);
+                                });
+    p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::SINK,
+                                [](const SupplicantStatus& status) {
+                                    EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                              status.code);
+                                });
+}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
index c50539b..c2a58b6 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -18,8 +18,122 @@
 
 #include <VtsHalHidlTargetTestBase.h>
 
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
+
 #include "supplicant_hidl_test_utils.h"
 
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIfaceCallback;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantNetworkId;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+
+namespace {
+constexpr uint8_t kTestMacAddr[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+constexpr ISupplicantStaIface::AnqpInfoId kTestAnqpInfoIds[] = {
+    ISupplicantStaIface::AnqpInfoId::VENUE_NAME,
+    ISupplicantStaIface::AnqpInfoId::NAI_REALM,
+    ISupplicantStaIface::AnqpInfoId::DOMAIN_NAME};
+constexpr ISupplicantStaIface::Hs20AnqpSubtypes kTestHs20Types[] = {
+    ISupplicantStaIface::Hs20AnqpSubtypes::WAN_METRICS,
+    ISupplicantStaIface::Hs20AnqpSubtypes::OPERATOR_FRIENDLY_NAME};
+constexpr char kTestHs20IconFile[] = "TestFile";
+constexpr int8_t kTestCountryCode[] = {'U', 'S'};
+}  // namespace
+
+class SupplicantStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        startSupplicantAndWaitForHidlService();
+        EXPECT_TRUE(turnOnExcessiveLogging());
+        sta_iface_ = getSupplicantStaIface();
+        ASSERT_NE(sta_iface_.get(), nullptr);
+
+        memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size());
+    }
+
+    virtual void TearDown() override { stopSupplicant(); }
+
+   protected:
+    // ISupplicantStaIface object used for all tests in this fixture.
+    sp<ISupplicantStaIface> sta_iface_;
+    // MAC address to use for various tests.
+    std::array<uint8_t, 6> mac_addr_;
+};
+
+class IfaceCallback : public ISupplicantStaIfaceCallback {
+    Return<void> onNetworkAdded(uint32_t /* id */) override { return Void(); }
+    Return<void> onNetworkRemoved(uint32_t /* id */) override { return Void(); }
+    Return<void> onStateChanged(
+        ISupplicantStaIfaceCallback::State /* newState */,
+        const hidl_array<uint8_t, 6>& /*bssid */, uint32_t /* id */,
+        const hidl_vec<uint8_t>& /* ssid */) override {
+        return Void();
+    }
+    Return<void> onAnqpQueryDone(
+        const hidl_array<uint8_t, 6>& /* bssid */,
+        const ISupplicantStaIfaceCallback::AnqpData& /* data */,
+        const ISupplicantStaIfaceCallback::Hs20AnqpData& /* hs20Data */)
+        override {
+        return Void();
+    }
+    virtual Return<void> onHs20IconQueryDone(
+        const hidl_array<uint8_t, 6>& /* bssid */,
+        const hidl_string& /* fileName */,
+        const hidl_vec<uint8_t>& /* data */) override {
+        return Void();
+    }
+    virtual Return<void> onHs20SubscriptionRemediation(
+        const hidl_array<uint8_t, 6>& /* bssid */,
+        ISupplicantStaIfaceCallback::OsuMethod /* osuMethod */,
+        const hidl_string& /* url*/) override {
+        return Void();
+    }
+    Return<void> onHs20DeauthImminentNotice(
+        const hidl_array<uint8_t, 6>& /* bssid */, uint32_t /* reasonCode */,
+        uint32_t /* reAuthDelayInSec */,
+        const hidl_string& /* url */) override {
+        return Void();
+    }
+    Return<void> onDisconnected(const hidl_array<uint8_t, 6>& /* bssid */,
+                                bool /* locallyGenerated */,
+                                uint32_t /* reasonCode */) override {
+        return Void();
+    }
+    Return<void> onAssociationRejected(
+        const hidl_array<uint8_t, 6>& /* bssid */, uint32_t /* statusCode */,
+        bool /*timedOut */) override {
+        return Void();
+    }
+    Return<void> onAuthenticationTimeout(
+        const hidl_array<uint8_t, 6>& /* bssid */) override {
+        return Void();
+    }
+    Return<void> onEapFailure() override { return Void(); }
+    Return<void> onWpsEventSuccess() override { return Void(); }
+    Return<void> onWpsEventFail(
+        const hidl_array<uint8_t, 6>& /* bssid */,
+        ISupplicantStaIfaceCallback::WpsConfigError /* configError */,
+        ISupplicantStaIfaceCallback::WpsErrorIndication /* errorInd */)
+        override {
+        return Void();
+    }
+    Return<void> onWpsEventPbcOverlap() override { return Void(); }
+    Return<void> onExtRadioWorkStart(uint32_t /* id */) override {
+        return Void();
+    }
+    Return<void> onExtRadioWorkTimeout(uint32_t /* id*/) override {
+        return Void();
+    }
+};
+
 /*
  * Create:
  * Ensures that an instance of the ISupplicantStaIface proxy object is
@@ -30,3 +144,257 @@
     EXPECT_NE(nullptr, getSupplicantStaIface().get());
     stopSupplicant();
 }
+
+/*
+ * RegisterCallback
+ */
+TEST_F(SupplicantStaIfaceHidlTest, RegisterCallback) {
+    sta_iface_->registerCallback(
+        new IfaceCallback(), [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * listNetworks.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, listNetworks) {
+    sta_iface_->listNetworks([](const SupplicantStatus& status,
+                                const hidl_vec<SupplicantNetworkId>& ids) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(0u, ids.size());
+    });
+
+    sp<ISupplicantStaNetwork> sta_network = createSupplicantStaNetwork();
+    EXPECT_NE(nullptr, sta_network.get());
+
+    sta_iface_->listNetworks([](const SupplicantStatus& status,
+                                const hidl_vec<SupplicantNetworkId>& ids) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_LT(0u, ids.size());
+    });
+}
+
+/*
+ * Reassociate.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, Reassociate) {
+    sta_iface_->reassociate([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * Reconnect.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, Reconnect) {
+    sta_iface_->reconnect([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED,
+                  status.code);
+    });
+}
+
+/*
+ * Disconnect.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, Disconnect) {
+    sta_iface_->disconnect([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * SetPowerSave.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetPowerSave) {
+    sta_iface_->setPowerSave(true, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_iface_->setPowerSave(false, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * InitiateTdlsDiscover.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateTdlsDiscover) {
+    sta_iface_->initiateTdlsDiscover(
+        mac_addr_, [](const SupplicantStatus& status) {
+            // These requests will fail unless the MAC address mentioned is
+            // actually around.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        });
+}
+
+/*
+ * InitiateTdlsSetup.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateTdlsSetup) {
+    sta_iface_->initiateTdlsSetup(
+        mac_addr_, [](const SupplicantStatus& status) {
+            // These requests will fail unless the MAC address mentioned is
+            // actually around.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        });
+}
+
+/*
+ * InitiateTdlsTeardown.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateTdlsTeardown) {
+    sta_iface_->initiateTdlsTeardown(
+        mac_addr_, [](const SupplicantStatus& status) {
+            // These requests will fail unless the MAC address mentioned is
+            // actually around.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        });
+}
+
+/*
+ * InitiateAnqpQuery.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateAnqpQuery) {
+    std::vector<ISupplicantStaIface::AnqpInfoId> anqp_ids(
+        kTestAnqpInfoIds, kTestAnqpInfoIds + sizeof(kTestAnqpInfoIds));
+    std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> hs_types(
+        kTestHs20Types, kTestHs20Types + sizeof(kTestHs20Types));
+    sta_iface_->initiateAnqpQuery(
+        mac_addr_, anqp_ids, hs_types, [](const SupplicantStatus& status) {
+            // These requests will fail unless the BSSID mentioned is actually
+            // present in scan results.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        });
+}
+
+/*
+ * InitiateHs20IconQuery.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateHs20IconQuery) {
+    sta_iface_->initiateHs20IconQuery(
+        mac_addr_, kTestHs20IconFile, [](const SupplicantStatus& status) {
+            // These requests will fail unless the BSSID mentioned is actually
+            // present in scan results.
+            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        });
+}
+
+/*
+ * GetMacAddress.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, GetMacAddress) {
+    sta_iface_->getMacAddress([](const SupplicantStatus& status,
+                                 const hidl_array<uint8_t, 6>& mac_addr) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        std::array<uint8_t, 6> std_mac_addr(mac_addr);
+        EXPECT_GT(6, std::count(std_mac_addr.begin(), std_mac_addr.end(), 0));
+    });
+}
+
+/*
+ * StartRxFilter.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, StartRxFilter) {
+    sta_iface_->startRxFilter([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * StopRxFilter.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, StopRxFilter) {
+    sta_iface_->stopRxFilter([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+}
+
+/*
+ * AddRxFilter.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, AddRxFilter) {
+    sta_iface_->addRxFilter(ISupplicantStaIface::RxFilterType::V4_MULTICAST,
+                            [](const SupplicantStatus& status) {
+                                EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                          status.code);
+                            });
+    sta_iface_->addRxFilter(ISupplicantStaIface::RxFilterType::V6_MULTICAST,
+                            [](const SupplicantStatus& status) {
+                                EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                          status.code);
+                            });
+}
+
+/*
+ * RemoveRxFilter.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, RemoveRxFilter) {
+    sta_iface_->removeRxFilter(ISupplicantStaIface::RxFilterType::V4_MULTICAST,
+                               [](const SupplicantStatus& status) {
+                                   EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                             status.code);
+                               });
+    sta_iface_->removeRxFilter(ISupplicantStaIface::RxFilterType::V6_MULTICAST,
+                               [](const SupplicantStatus& status) {
+                                   EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+                                             status.code);
+                               });
+}
+
+/*
+ * SetBtCoexistenceMode.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetBtCoexistenceMode) {
+    sta_iface_->setBtCoexistenceMode(
+        ISupplicantStaIface::BtCoexistenceMode::ENABLED,
+        [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_iface_->setBtCoexistenceMode(
+        ISupplicantStaIface::BtCoexistenceMode::DISABLED,
+        [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_iface_->setBtCoexistenceMode(
+        ISupplicantStaIface::BtCoexistenceMode::SENSE,
+        [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * SetBtCoexistenceScanModeEnabled.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetBtCoexistenceScanModeEnabled) {
+    sta_iface_->setBtCoexistenceScanModeEnabled(
+        true, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_iface_->setBtCoexistenceScanModeEnabled(
+        false, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * SetSuspendModeEnabled.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetSuspendModeEnabled) {
+    sta_iface_->setSuspendModeEnabled(true, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_iface_->setSuspendModeEnabled(
+        false, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * SetCountryCode.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetCountryCode) {
+    sta_iface_->setCountryCode(
+        kTestCountryCode, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
index cde75fa..aa84e9a 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -18,8 +18,104 @@
 
 #include <VtsHalHidlTargetTestBase.h>
 
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
+
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
+
 #include "supplicant_hidl_test_utils.h"
 
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
+using ::android::hardware::wifi::supplicant::V1_0::
+    ISupplicantStaNetworkCallback;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+
+namespace {
+constexpr char kTestSsidStr[] = "TestSsid1234";
+constexpr char kTestPsk[] = "TestPsk123";
+constexpr char kTestIdStr[] = "TestIdstr";
+constexpr char kTestEapPasswdStr[] = "TestEapPasswd1234";
+constexpr char kTestEapCert[] = "keystore://CERT";
+constexpr char kTestEapPrivateKeyId[] = "key_id";
+constexpr char kTestEapMatch[] = "match";
+constexpr char kTestEapEngineID[] = "engine_id";
+constexpr uint8_t kTestBssid[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+constexpr uint8_t kTestWepKey[] = {0x56, 0x67, 0x67, 0xf4, 0x56};
+constexpr uint8_t kTestKc[] = {0x56, 0x67, 0x67, 0xf4, 0x76, 0x87, 0x98, 0x12};
+constexpr uint8_t kTestSres[] = {0x56, 0x67, 0x67, 0xf4};
+constexpr uint8_t kTestRes[] = {0x56, 0x67, 0x67, 0xf4, 0x67};
+constexpr uint8_t kTestIk[] = {[0 ... 15] = 0x65};
+constexpr uint8_t kTestCk[] = {[0 ... 15] = 0x45};
+constexpr uint8_t kTestIdentity[] = {0x45, 0x67, 0x98, 0x67, 0x56};
+constexpr uint32_t kTestWepTxKeyIdx = 2;
+constexpr uint32_t kTestKeyMgmt = (ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK |
+                                   ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP);
+constexpr uint32_t kTestProto = (ISupplicantStaNetwork::ProtoMask::OSEN |
+                                 ISupplicantStaNetwork::ProtoMask::RSN);
+constexpr uint32_t kTestAuthAlg = (ISupplicantStaNetwork::AuthAlgMask::OPEN |
+                                   ISupplicantStaNetwork::AuthAlgMask::SHARED);
+constexpr uint32_t kTestGroupCipher =
+    (ISupplicantStaNetwork::GroupCipherMask::CCMP |
+     ISupplicantStaNetwork::GroupCipherMask::WEP104);
+constexpr uint32_t kTestPairwiseCipher =
+    (ISupplicantStaNetwork::PairwiseCipherMask::CCMP |
+     ISupplicantStaNetwork::PairwiseCipherMask::TKIP);
+}  // namespace
+
+class SupplicantStaNetworkHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        startSupplicantAndWaitForHidlService();
+        EXPECT_TRUE(turnOnExcessiveLogging());
+        sta_network_ = createSupplicantStaNetwork();
+        ASSERT_NE(sta_network_.get(), nullptr);
+
+        ssid_.assign(kTestSsidStr, kTestSsidStr + strlen(kTestSsidStr));
+    }
+
+    virtual void TearDown() override { stopSupplicant(); }
+
+   protected:
+    void removeNetwork() {
+      sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface();
+      ASSERT_NE(nullptr, sta_iface.get());
+      uint32_t net_id;
+      sta_network_->getId([&](const SupplicantStatus& status, int network_id) {
+              ASSERT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+              net_id = network_id;
+          });
+      sta_iface->removeNetwork(net_id, [](const SupplicantStatus& status) {
+              ASSERT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+          });
+    }
+
+    // ISupplicantStaNetwork object used for all tests in this fixture.
+    sp<ISupplicantStaNetwork> sta_network_;
+    // SSID to use for various tests.
+    std::vector<uint8_t> ssid_;
+};
+
+class NetworkCallback : public ISupplicantStaNetworkCallback {
+    Return<void> onNetworkEapSimGsmAuthRequest(
+        const ISupplicantStaNetworkCallback::NetworkRequestEapSimGsmAuthParams&
+        /* params */) override {
+        return Void();
+    }
+    Return<void> onNetworkEapSimUmtsAuthRequest(
+        const ISupplicantStaNetworkCallback::NetworkRequestEapSimUmtsAuthParams&
+        /* params */) override {
+        return Void();
+    }
+    Return<void> onNetworkEapIdentityRequest() override { return Void(); }
+};
+
 /*
  * Create:
  * Ensures that an instance of the ISupplicantStaNetwork proxy object is
@@ -30,3 +126,535 @@
     EXPECT_NE(nullptr, createSupplicantStaNetwork().get());
     stopSupplicant();
 }
+
+/*
+ * RegisterCallback
+ */
+TEST_F(SupplicantStaNetworkHidlTest, RegisterCallback) {
+    sta_network_->registerCallback(
+        new NetworkCallback(), [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/* Tests out the various setter/getter methods. */
+/*
+ * SetGetSsid
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetSsid) {
+    sta_network_->setSsid(ssid_, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_network_->getSsid(
+        [&](const SupplicantStatus& status, const hidl_vec<uint8_t>& get_ssid) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(ssid_, std::vector<uint8_t>(get_ssid));
+        });
+}
+
+/*
+ * SetGetBssid
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetBssid) {
+    std::array<uint8_t, 6> set_bssid;
+    memcpy(set_bssid.data(), kTestBssid, set_bssid.size());
+    sta_network_->setBssid(set_bssid, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_network_->getBssid([&](const SupplicantStatus& status,
+                               const hidl_array<uint8_t, 6>& get_bssid_hidl) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        std::array<uint8_t, 6> get_bssid;
+        memcpy(get_bssid.data(), get_bssid_hidl.data(), get_bssid.size());
+        EXPECT_EQ(set_bssid, get_bssid);
+    });
+}
+
+/*
+ * SetGetKeyMgmt
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetKeyMgmt) {
+    sta_network_->setKeyMgmt(kTestKeyMgmt, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_network_->getKeyMgmt(
+        [&](const SupplicantStatus& status, uint32_t key_mgmt) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(key_mgmt, kTestKeyMgmt);
+        });
+}
+
+/*
+ * SetGetProto
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetProto) {
+    sta_network_->setProto(kTestProto, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_network_->getProto([&](const SupplicantStatus& status, uint32_t proto) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(proto, kTestProto);
+    });
+}
+
+/*
+ * SetGetKeyAuthAlg
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetAuthAlg) {
+    sta_network_->setAuthAlg(kTestAuthAlg, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_network_->getAuthAlg(
+        [&](const SupplicantStatus& status, uint32_t auth_alg) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(auth_alg, kTestAuthAlg);
+        });
+}
+
+/*
+ * SetGetGroupCipher
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetGroupCipher) {
+    sta_network_->setGroupCipher(
+        kTestGroupCipher, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getGroupCipher(
+        [&](const SupplicantStatus& status, uint32_t group_cipher) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(group_cipher, kTestGroupCipher);
+        });
+}
+
+/*
+ * SetGetPairwiseCipher
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetPairwiseCipher) {
+    sta_network_->setPairwiseCipher(
+        kTestPairwiseCipher, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getPairwiseCipher(
+        [&](const SupplicantStatus& status, uint32_t pairwise_cipher) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(pairwise_cipher, kTestPairwiseCipher);
+        });
+}
+
+/*
+ * SetGetPskPassphrase
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetPskPassphrase) {
+    sta_network_->setPskPassphrase(
+        kTestPsk, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getPskPassphrase(
+        [&](const SupplicantStatus& status, const hidl_string& psk) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(kTestPsk, std::string(psk.c_str()));
+        });
+}
+
+/*
+ * SetGetWepKeys
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetWepTxKeyIdx) {
+    sta_network_->setWepTxKeyIdx(
+        kTestWepTxKeyIdx, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getWepTxKeyIdx(
+        [&](const SupplicantStatus& status, uint32_t key_idx) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(kTestWepTxKeyIdx, key_idx);
+        });
+}
+
+/*
+ * SetGetWepKeys
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetWepKeys) {
+    for (uint32_t i = 0;
+         i < static_cast<uint32_t>(
+                 ISupplicantStaNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM);
+         i++) {
+        std::vector<uint8_t> set_wep_key(std::begin(kTestWepKey),
+                                         std::end(kTestWepKey));
+        sta_network_->setWepKey(
+            i, set_wep_key, [](const SupplicantStatus& status) {
+                EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            });
+        sta_network_->getWepKey(i, [&](const SupplicantStatus& status,
+                                       const hidl_vec<uint8_t>& get_wep_key) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(set_wep_key, std::vector<uint8_t>(get_wep_key));
+        });
+    }
+}
+
+/*
+ * SetGetScanSsid
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetScanSsid) {
+    sta_network_->setScanSsid(
+        true, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getScanSsid(
+        [&](const SupplicantStatus& status, bool scan_ssid) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(true, scan_ssid);
+        });
+}
+
+/*
+ * SetGetRequirePmf
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetRequirePmf) {
+    sta_network_->setRequirePmf(
+        true, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getRequirePmf(
+        [&](const SupplicantStatus& status, bool require_pmf) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(true, require_pmf);
+        });
+}
+
+/*
+ * SetGetIdStr
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetIdStr) {
+    sta_network_->setIdStr(
+        kTestIdStr, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getIdStr(
+        [&](const SupplicantStatus& status, const hidl_string& id_str) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(kTestIdStr, std::string(id_str.c_str()));
+        });
+}
+
+
+/*
+ * SetGetEapMethod
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapMethod) {
+    ISupplicantStaNetwork::EapMethod set_eap_method =
+        ISupplicantStaNetwork::EapMethod::PEAP;
+    sta_network_->setEapMethod(
+        set_eap_method, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapMethod(
+        [&](const SupplicantStatus& status,
+            ISupplicantStaNetwork::EapMethod eap_method) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(set_eap_method, eap_method);
+        });
+}
+
+/*
+ * SetGetEapPhase2Method
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPhase2Method) {
+    ISupplicantStaNetwork::EapPhase2Method set_eap_phase2_method =
+        ISupplicantStaNetwork::EapPhase2Method::NONE;
+    sta_network_->setEapPhase2Method(
+        set_eap_phase2_method, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapPhase2Method(
+        [&](const SupplicantStatus& status,
+            ISupplicantStaNetwork::EapPhase2Method eap_phase2_method) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(set_eap_phase2_method, eap_phase2_method);
+        });
+}
+
+/*
+ * SetGetEapIdentity
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapIdentity) {
+    std::vector<uint8_t> set_identity(kTestIdentity, kTestIdentity + sizeof(kTestIdentity));
+    sta_network_->setEapIdentity(
+        set_identity, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapIdentity(
+        [&](const SupplicantStatus& status, const std::vector<uint8_t>& identity) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(set_identity, identity);
+        });
+}
+
+/*
+ * SetGetEapAnonymousIdentity
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapAnonymousIdentity) {
+    std::vector<uint8_t> set_identity(kTestIdentity, kTestIdentity + sizeof(kTestIdentity));
+    sta_network_->setEapAnonymousIdentity(
+        set_identity, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapAnonymousIdentity(
+        [&](const SupplicantStatus& status, const std::vector<uint8_t>& identity) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(set_identity, identity);
+        });
+}
+
+/*
+ * SetGetEapPassword
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPassword) {
+    std::vector<uint8_t> set_eap_passwd(
+        kTestEapPasswdStr, kTestEapPasswdStr + strlen(kTestEapPasswdStr));
+    sta_network_->setEapPassword(
+        set_eap_passwd, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapPassword([&](const SupplicantStatus& status,
+                                     const hidl_vec<uint8_t>& eap_passwd) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(set_eap_passwd, std::vector<uint8_t>(eap_passwd));
+    });
+}
+
+/*
+ * SetGetEapCACert
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapCACert) {
+    sta_network_->setEapCACert(
+        kTestEapCert, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapCACert([&](const SupplicantStatus& status,
+                                   const hidl_string& eap_cert) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(kTestEapCert, std::string(eap_cert.c_str()));
+    });
+}
+
+/*
+ * SetGetEapCAPath
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapCAPath) {
+    sta_network_->setEapCAPath(
+        kTestEapCert, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapCAPath([&](const SupplicantStatus& status,
+                                   const hidl_string& eap_cert) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(kTestEapCert, std::string(eap_cert.c_str()));
+    });
+}
+
+/*
+ * SetGetEapClientCert
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapClientCert) {
+    sta_network_->setEapClientCert(
+        kTestEapCert, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapClientCert([&](const SupplicantStatus& status,
+                                       const hidl_string& eap_cert) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(kTestEapCert, std::string(eap_cert.c_str()));
+    });
+}
+
+/*
+ * SetGetEapPrivateKeyId
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPrivateKeyId) {
+    sta_network_->setEapPrivateKeyId(
+        kTestEapPrivateKeyId, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapPrivateKeyId([&](const SupplicantStatus& status,
+                                         const hidl_string& key_id) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(kTestEapPrivateKeyId, std::string(key_id.c_str()));
+    });
+}
+
+/*
+ * SetGetEapAltSubjectMatch
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapAltSubjectMatch) {
+    sta_network_->setEapAltSubjectMatch(
+        kTestEapMatch, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapAltSubjectMatch([&](const SupplicantStatus& status,
+                                            const hidl_string& match) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(kTestEapMatch, std::string(match.c_str()));
+    });
+}
+
+/*
+ * SetGetEapDomainSuffixMatch
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapDomainSuffixMatch) {
+    sta_network_->setEapDomainSuffixMatch(
+        kTestEapMatch, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapDomainSuffixMatch([&](const SupplicantStatus& status,
+                                              const hidl_string& match) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(kTestEapMatch, std::string(match.c_str()));
+    });
+}
+
+/*
+ * SetGetEapEngine
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapEngine) {
+    sta_network_->setEapEngine(
+        true, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapEngine([&](const SupplicantStatus& status,
+                                   bool enable) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(true, enable);
+    });
+}
+
+/*
+ * SetGetEapEngineID
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapEngineID) {
+    sta_network_->setEapEngineID(
+        kTestEapEngineID, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+    sta_network_->getEapEngineID([&](const SupplicantStatus& status,
+                                     const hidl_string& id) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        EXPECT_EQ(kTestEapEngineID, std::string(id.c_str()));
+    });
+}
+
+/*
+ * Enable
+ */
+TEST_F(SupplicantStaNetworkHidlTest, Enable) {
+    // wpa_supplicant doesn't perform any connection initiation
+    // unless atleast the Ssid and Ket mgmt params are set.
+    sta_network_->setSsid(ssid_, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_network_->setKeyMgmt(kTestKeyMgmt, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+
+    sta_network_->enable(false, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_network_->enable(true, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+
+    // Now remove the network and ensure that the calls fail.
+    removeNetwork();
+    sta_network_->enable(true, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::FAILURE_NETWORK_INVALID, status.code);
+    });
+}
+
+/*
+ * Disable
+ */
+TEST_F(SupplicantStaNetworkHidlTest, Disable) {
+    // wpa_supplicant doesn't perform any connection initiation
+    // unless atleast the Ssid and Ket mgmt params are set.
+    sta_network_->setSsid(ssid_, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_network_->setKeyMgmt(kTestKeyMgmt, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+
+    sta_network_->disable([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    // Now remove the network and ensure that the calls fail.
+    removeNetwork();
+    sta_network_->disable([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::FAILURE_NETWORK_INVALID, status.code);
+    });
+}
+
+/*
+ * Select.
+ */
+TEST_F(SupplicantStaNetworkHidlTest, Select) {
+    // wpa_supplicant doesn't perform any connection initiation
+    // unless atleast the Ssid and Ket mgmt params are set.
+    sta_network_->setSsid(ssid_, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    sta_network_->setKeyMgmt(kTestKeyMgmt, [](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+
+    sta_network_->select([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    });
+    // Now remove the network and ensure that the calls fail.
+    removeNetwork();
+    sta_network_->select([](const SupplicantStatus& status) {
+        EXPECT_EQ(SupplicantStatusCode::FAILURE_NETWORK_INVALID, status.code);
+    });
+}
+
+/*
+ * SendNetworkEapSimGsmAuthResponse
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimGsmAuthResponse) {
+    std::vector<ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams>
+        params;
+    ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams param;
+    memcpy(param.kc.data(), kTestKc, param.kc.size());
+    memcpy(param.sres.data(), kTestSres, param.sres.size());
+    params.push_back(param);
+    sta_network_->sendNetworkEapSimGsmAuthResponse(
+        params, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * SendNetworkEapSimUmtsAuthResponse
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAuthResponse) {
+    ISupplicantStaNetwork::NetworkResponseEapSimUmtsAuthParams params;
+    params.res = std::vector<uint8_t>(kTestRes, kTestRes + sizeof(kTestRes));
+    memcpy(params.ik.data(), kTestIk, params.ik.size());
+    memcpy(params.ck.data(), kTestCk, params.ck.size());
+    sta_network_->sendNetworkEapSimUmtsAuthResponse(
+        params, [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * SendNetworkEapIdentityResponse
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapIdentityResponse) {
+    sta_network_->sendNetworkEapIdentityResponse(
+        std::vector<uint8_t>(kTestIdentity,
+                             kTestIdentity + sizeof(kTestIdentity)),
+        [](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}