Merge "Add the error code "OPERATION_NOT_ALLOWED" and log the error." into oc-dr1-dev
diff --git a/audio/2.0/config/audio_policy_configuration.xsd b/audio/2.0/config/audio_policy_configuration.xsd
index 48b9a9b..c94da80 100644
--- a/audio/2.0/config/audio_policy_configuration.xsd
+++ b/audio/2.0/config/audio_policy_configuration.xsd
@@ -188,6 +188,7 @@
                 <xs:complexType>
                     <xs:sequence>
                         <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
                     </xs:sequence>
                     <xs:attribute name="name" type="xs:token" use="required"/>
                     <xs:attribute name="role" type="role" use="required"/>
@@ -199,6 +200,10 @@
                     <xs:field xpath="samplingRate"/>
                     <xs:field xpath="channelMasks"/>
                 </xs:unique>
+                <xs:unique name="mixPortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
             </xs:element>
         </xs:sequence>
     </xs:complexType>
@@ -365,16 +370,42 @@
         <xs:attribute name="samplingRates" type="samplingRates" use="required"/>
         <xs:attribute name="channelMasks" type="channelMask" use="required"/>
     </xs:complexType>
+    <xs:simpleType name="gainMode">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_GAIN_MODE_JOINT"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_CHANNELS"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_RAMP"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="gains">
+        <xs:sequence>
+            <xs:element name="gain" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:token" use="required"/>
+                    <xs:attribute name="mode" type="gainMode" use="required"/>
+                    <xs:attribute name="channel_mask" type="channelMask" use="optional"/>
+                    <xs:attribute name="minValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="defaultValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="stepValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="minRampMs" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxRampMs" type="xs:int" use="optional"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
     <xs:complexType name="devicePorts">
         <xs:sequence>
             <xs:element name="devicePort" minOccurs="0" maxOccurs="unbounded">
                 <xs:complexType>
                     <xs:sequence>
                         <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
                     </xs:sequence>
                     <xs:attribute name="tagName" type="xs:token" use="required"/>
                     <xs:attribute name="type" type="audioDevice" use="required"/>
                     <xs:attribute name="role" type="role" use="required"/>
+                    <xs:attribute name="address" type="xs:string" use="optional"/>
                 </xs:complexType>
                 <xs:unique name="devicePortProfileUniqueness">
                     <xs:selector xpath="profile"/>
@@ -382,6 +413,10 @@
                     <xs:field xpath="samplingRate"/>
                     <xs:field xpath="channelMasks"/>
                 </xs:unique>
+                <xs:unique name="devicePortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
             </xs:element>
         </xs:sequence>
     </xs:complexType>
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index a27fd66..3b9d35c 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -2458,7 +2458,8 @@
                     Stream stream = {streamId, StreamType::OUTPUT,
                             static_cast<uint32_t> (it.width),
                             static_cast<uint32_t> (it.height),
-                            static_cast<PixelFormat> (it.format), 0, 0,
+                            static_cast<PixelFormat> (it.format),
+                            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
                             StreamRotation::ROTATION_0};
                     ::android::hardware::hidl_vec<Stream> streams = {stream};
                     StreamConfiguration config = {streams,
@@ -2507,7 +2508,8 @@
                         static_cast<uint32_t> (0),
                         static_cast<uint32_t> (0),
                         static_cast<PixelFormat> (outputStreams[0].format),
-                        0, 0, StreamRotation::ROTATION_0};
+                        GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                        StreamRotation::ROTATION_0};
                 ::android::hardware::hidl_vec<Stream> streams = {stream};
                 StreamConfiguration config = {streams,
                         StreamConfigurationMode::NORMAL_MODE};
@@ -2522,7 +2524,8 @@
                         static_cast<uint32_t> (UINT32_MAX),
                         static_cast<uint32_t> (UINT32_MAX),
                         static_cast<PixelFormat> (outputStreams[0].format),
-                        0, 0, StreamRotation::ROTATION_0};
+                        GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                        StreamRotation::ROTATION_0};
                 streams[0] = stream;
                 config = {streams,
                         StreamConfigurationMode::NORMAL_MODE};
@@ -2537,7 +2540,8 @@
                             static_cast<uint32_t> (it.width),
                             static_cast<uint32_t> (it.height),
                             static_cast<PixelFormat> (UINT32_MAX),
-                            0, 0, StreamRotation::ROTATION_0};
+                            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                            StreamRotation::ROTATION_0};
                     streams[0] = stream;
                     config = {streams,
                             StreamConfigurationMode::NORMAL_MODE};
@@ -2551,7 +2555,8 @@
                             static_cast<uint32_t> (it.width),
                             static_cast<uint32_t> (it.height),
                             static_cast<PixelFormat> (it.format),
-                            0, 0, static_cast<StreamRotation> (UINT32_MAX)};
+                            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+                            static_cast<StreamRotation> (UINT32_MAX)};
                     streams[0] = stream;
                     config = {streams,
                             StreamConfigurationMode::NORMAL_MODE};
@@ -2633,7 +2638,8 @@
                         Stream outputStream = {streamId++, StreamType::OUTPUT,
                                 static_cast<uint32_t> (outputIter.width),
                                 static_cast<uint32_t> (outputIter.height),
-                                static_cast<PixelFormat> (outputIter.format), 0, 0,
+                                static_cast<PixelFormat> (outputIter.format),
+                                GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
                                 StreamRotation::ROTATION_0};
 
                         ::android::hardware::hidl_vec<Stream> streams = {
@@ -2695,12 +2701,14 @@
                         Stream previewStream = {streamId++, StreamType::OUTPUT,
                                 static_cast<uint32_t> (previewIter.width),
                                 static_cast<uint32_t> (previewIter.height),
-                                static_cast<PixelFormat> (previewIter.format), 0, 0,
+                                static_cast<PixelFormat> (previewIter.format),
+                                GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
                                 StreamRotation::ROTATION_0};
                         Stream blobStream = {streamId++, StreamType::OUTPUT,
                                 static_cast<uint32_t> (blobIter.width),
                                 static_cast<uint32_t> (blobIter.height),
-                                static_cast<PixelFormat> (blobIter.format), 0, 0,
+                                static_cast<PixelFormat> (blobIter.format),
+                                GRALLOC1_CONSUMER_USAGE_CPU_READ, 0,
                                 StreamRotation::ROTATION_0};
                         ::android::hardware::hidl_vec<Stream> streams = {
                                 previewStream, blobStream};
@@ -2756,7 +2764,8 @@
                 Stream stream = {streamId, StreamType::OUTPUT,
                         static_cast<uint32_t> (hfrStream.width),
                         static_cast<uint32_t> (hfrStream.height),
-                        static_cast<PixelFormat> (hfrStream.format), 0, 0,
+                        static_cast<PixelFormat> (hfrStream.format),
+                        GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
                         StreamRotation::ROTATION_0};
                 ::android::hardware::hidl_vec<Stream> streams = {stream};
                 StreamConfiguration config = {streams,
@@ -2772,7 +2781,8 @@
                 stream = {streamId++, StreamType::OUTPUT,
                         static_cast<uint32_t> (0),
                         static_cast<uint32_t> (0),
-                        static_cast<PixelFormat> (hfrStream.format), 0, 0,
+                        static_cast<PixelFormat> (hfrStream.format),
+                        GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
                         StreamRotation::ROTATION_0};
                 streams[0] = stream;
                 config = {streams,
@@ -2787,7 +2797,8 @@
                 stream = {streamId++, StreamType::OUTPUT,
                         static_cast<uint32_t> (UINT32_MAX),
                         static_cast<uint32_t> (UINT32_MAX),
-                        static_cast<PixelFormat> (hfrStream.format), 0, 0,
+                        static_cast<PixelFormat> (hfrStream.format),
+                        GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
                         StreamRotation::ROTATION_0};
                 streams[0] = stream;
                 config = {streams,
@@ -2801,7 +2812,8 @@
                 stream = {streamId++, StreamType::OUTPUT,
                         static_cast<uint32_t> (hfrStream.width),
                         static_cast<uint32_t> (hfrStream.height),
-                        static_cast<PixelFormat> (UINT32_MAX), 0, 0,
+                        static_cast<PixelFormat> (UINT32_MAX),
+                        GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
                         StreamRotation::ROTATION_0};
                 streams[0] = stream;
                 config = {streams,
@@ -2859,12 +2871,13 @@
                                 static_cast<uint32_t> (videoIter.width),
                                 static_cast<uint32_t> (videoIter.height),
                                 static_cast<PixelFormat> (videoIter.format),
-                                0, 0, StreamRotation::ROTATION_0};
+                                GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
+                                StreamRotation::ROTATION_0};
                         Stream blobStream = {streamId++, StreamType::OUTPUT,
                                 static_cast<uint32_t> (blobIter.width),
                                 static_cast<uint32_t> (blobIter.height),
                                 static_cast<PixelFormat> (blobIter.format),
-                                GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
+                                GRALLOC1_CONSUMER_USAGE_CPU_READ, 0,
                                 StreamRotation::ROTATION_0};
                         ::android::hardware::hidl_vec<Stream> streams = {
                                 videoStream, blobStream};
@@ -3587,7 +3600,7 @@
             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};
+            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0};
     ::android::hardware::hidl_vec<Stream> streams = {*previewStream};
     StreamConfiguration config = {streams,
             StreamConfigurationMode::NORMAL_MODE};
diff --git a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h b/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
index ada7d09..e332086 100644
--- a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
+++ b/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
@@ -51,7 +51,7 @@
   // the set of all currently connected displays
   std::unordered_set<Display> mDisplays;
   // true only when vsync is enabled
-  bool mVsyncAllowed = false;
+  bool mVsyncAllowed = true;
 
   // track invalid callbacks
   int mInvalidHotplugCount = 0;
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
index 4e65a95..c66cdd0 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
@@ -297,6 +297,11 @@
                                            : IComposerClient::Vsync::DISABLE;
   Error error = mClient->setVsyncEnabled(display, vsync);
   ASSERT_EQ(Error::NONE, error) << "failed to set vsync mode";
+
+  // give the hwbinder thread some time to handle any pending vsync callback
+  if (!enabled) {
+      usleep(5 * 1000);
+  }
 }
 
 void ComposerClient::execute(TestCommandReader* reader,
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index c77b7d3..0f03546 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -61,6 +61,10 @@
 
     // assume the first display is primary and is never removed
     mPrimaryDisplay = waitForFirstDisplay();
+
+    // explicitly disable vsync
+    mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
+    mComposerCallback->setVsyncAllowed(false);
   }
 
   void TearDown() override {
diff --git a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
index c833407..336cab4 100644
--- a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
+++ b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
@@ -485,15 +485,20 @@
 
 // port settings reconfiguration during runtime. reconfigures sample rate and
 // number
+typedef struct {
+    OMX_AUDIO_CODINGTYPE eEncoding;
+    AudioDecHidlTest::standardComp comp;
+} packedArgs;
 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                          android::Vector<BufferInfo>* iBuffer,
                          android::Vector<BufferInfo>* oBuffer,
-                         OMX_AUDIO_CODINGTYPE eEncoding,
                          OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
-                         Message msg,
-                         AudioDecHidlTest::standardComp comp =
-                             AudioDecHidlTest::standardComp::unknown_comp) {
+                         Message msg, PortMode oPortMode, void* args) {
     android::hardware::media::omx::V1_0::Status status;
+    packedArgs* audioArgs = static_cast<packedArgs*>(args);
+    OMX_AUDIO_CODINGTYPE eEncoding = audioArgs->eEncoding;
+    AudioDecHidlTest::standardComp comp = audioArgs->comp;
+    (void)oPortMode;
 
     if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
         ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
@@ -579,7 +584,8 @@
                             android::Vector<BufferInfo>* iBuffer,
                             android::Vector<BufferInfo>* oBuffer,
                             OMX_AUDIO_CODINGTYPE eEncoding,
-                            OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput) {
+                            OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
+                            AudioDecHidlTest::standardComp comp) {
     android::hardware::media::omx::V1_0::Status status;
     Message msg;
     int timeOut = TIMEOUT_COUNTER;
@@ -590,8 +596,10 @@
             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
         if (status == android::hardware::media::omx::V1_0::Status::OK) {
             EXPECT_EQ(msg.type, Message::Type::EVENT);
-            portReconfiguration(omxNode, observer, iBuffer, oBuffer, eEncoding,
-                                kPortIndexInput, kPortIndexOutput, msg);
+            packedArgs audioArgs = {eEncoding, comp};
+            portReconfiguration(omxNode, observer, iBuffer, oBuffer,
+                                kPortIndexInput, kPortIndexOutput, msg,
+                                PortMode::PRESET_BYTE_BUFFER, &audioArgs);
         }
         // status == TIMED_OUT, it could be due to process time being large
         // than DEFAULT_TIMEOUT or component needs output buffers to start
@@ -655,8 +663,10 @@
         // Port Reconfiguration
         if (status == android::hardware::media::omx::V1_0::Status::OK &&
             msg.type == Message::Type::EVENT) {
-            portReconfiguration(omxNode, observer, iBuffer, oBuffer, eEncoding,
-                                kPortIndexInput, kPortIndexOutput, msg, comp);
+            packedArgs audioArgs = {eEncoding, comp};
+            portReconfiguration(omxNode, observer, iBuffer, oBuffer,
+                                kPortIndexInput, kPortIndexOutput, msg,
+                                PortMode::PRESET_BYTE_BUFFER, &audioArgs);
         }
 
         if (frameID == (int)Info->size() || frameID == (offset + range)) break;
@@ -800,8 +810,10 @@
                   (int)Info.size(), compName);
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
-                           kPortIndexInput, kPortIndexOutput);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag);
+                           kPortIndexInput, kPortIndexOutput, compName);
+    packedArgs audioArgs = {eEncoding, compName};
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     EXPECT_EQ(timestampUslist.empty(), true);
     // set state to idle
     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
@@ -857,7 +869,9 @@
     changeStateIdletoExecute(omxNode, observer);
 
     // request EOS at the start
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
+    packedArgs audioArgs = {eEncoding, compName};
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 0U);
@@ -944,8 +958,10 @@
                   compName);
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
-                           kPortIndexInput, kPortIndexOutput);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag);
+                           kPortIndexInput, kPortIndexOutput, compName);
+    packedArgs audioArgs = {eEncoding, compName};
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 1U);
@@ -960,8 +976,9 @@
                   compName, false);
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
-                           kPortIndexInput, kPortIndexOutput);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
+                           kPortIndexInput, kPortIndexOutput, compName);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 1U);
@@ -1045,8 +1062,10 @@
                   (int)Info.size(), compName, false);
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
-                           kPortIndexInput, kPortIndexOutput);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
+                           kPortIndexInput, kPortIndexOutput, compName);
+    packedArgs audioArgs = {eEncoding, compName};
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     framesReceived = 0;
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
index e81e6dd..700d2f3 100755
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
@@ -406,7 +406,8 @@
 void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
              android::Vector<BufferInfo>* iBuffer,
              android::Vector<BufferInfo>* oBuffer, bool signalEOS,
-             bool& eosFlag, PortMode* portMode) {
+             bool& eosFlag, PortMode* portMode, portreconfig fptr,
+             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput, void* args) {
     android::hardware::media::omx::V1_0::Status status;
     PortMode defaultPortMode[2], *pm;
 
@@ -443,9 +444,15 @@
         status =
             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
         if (status == android::hardware::media::omx::V1_0::Status::OK) {
-            if (msg.data.eventData.event == OMX_EventBufferFlag) {
-                // soft omx components donot send this, we will just ignore it
-                // for now
+            if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
+                if (fptr) {
+                    (*fptr)(omxNode, observer, iBuffer, oBuffer,
+                            kPortIndexInput, kPortIndexOutput, msg, pm[1],
+                            args);
+                } else {
+                    // something unexpected happened
+                    EXPECT_TRUE(false);
+                }
             } else {
                 // something unexpected happened
                 EXPECT_TRUE(false);
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
index d617e45..354b7a7 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
@@ -113,6 +113,12 @@
                     android::hardware::media::omx::V1_0::Message::Type::EVENT) {
                     *msg = *it;
                     msgQueue.erase(it);
+                    // OMX_EventBufferFlag event is sent when the component has
+                    // processed a buffer with its EOS flag set. This event is
+                    // not sent by soft omx components. Vendor components can
+                    // send this. From IOMX point of view, we will ignore this
+                    // event.
+                    if (msg->data.eventData.event == OMX_EventBufferFlag) break;
                     return ::android::hardware::media::omx::V1_0::Status::OK;
                 } else if (it->type == android::hardware::media::omx::V1_0::
                                            Message::Type::FILL_BUFFER_DONE) {
@@ -299,9 +305,16 @@
                 android::Vector<BufferInfo>* oBuffer, OMX_U32 kPortIndexInput,
                 OMX_U32 kPortIndexOutput, int64_t timeoutUs = DEFAULT_TIMEOUT);
 
+typedef void (*portreconfig)(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
+                             android::Vector<BufferInfo>* iBuffer,
+                             android::Vector<BufferInfo>* oBuffer,
+                             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
+                             Message msg, PortMode oPortMode, void* args);
 void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
              android::Vector<BufferInfo>* iBuffer,
              android::Vector<BufferInfo>* oBuffer, bool signalEOS,
-             bool& eosFlag, PortMode* portMode = nullptr);
+             bool& eosFlag, PortMode* portMode = nullptr,
+             portreconfig fptr = nullptr, OMX_U32 kPortIndexInput = 0,
+             OMX_U32 kPortIndexOutput = 1, void* args = nullptr);
 
 #endif  // MEDIA_HIDL_TEST_COMMON_H
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
index ac7f829..98b0317 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
@@ -485,8 +485,9 @@
                          android::Vector<BufferInfo>* iBuffer,
                          android::Vector<BufferInfo>* oBuffer,
                          OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
-                         Message msg, PortMode oPortMode) {
+                         Message msg, PortMode oPortMode, void* args) {
     android::hardware::media::omx::V1_0::Status status;
+    (void)args;
 
     if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
         ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
@@ -586,9 +587,6 @@
         std::cout << "[          ] Warning ! OMX_EventError/ "
                      "Decode Frame Call might be failed \n";
         return;
-    } else if (msg.data.eventData.event == OMX_EventBufferFlag) {
-        // soft omx components donot send this, we will just ignore it
-        // for now
     } else {
         // something unexpected happened
         ASSERT_TRUE(false);
@@ -613,7 +611,7 @@
             EXPECT_EQ(msg.type, Message::Type::EVENT);
             portReconfiguration(omxNode, observer, iBuffer, oBuffer,
                                 kPortIndexInput, kPortIndexOutput, msg,
-                                oPortMode);
+                                oPortMode, nullptr);
         }
         // status == TIMED_OUT, it could be due to process time being large
         // than DEFAULT_TIMEOUT or component needs output buffers to start
@@ -679,7 +677,7 @@
             msg.type == Message::Type::EVENT) {
             portReconfiguration(omxNode, observer, iBuffer, oBuffer,
                                 kPortIndexInput, kPortIndexOutput, msg,
-                                oPortMode);
+                                oPortMode, nullptr);
         }
 
         if (frameID == (int)Info->size() || frameID == (offset + range)) break;
@@ -845,7 +843,8 @@
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
                            kPortIndexInput, kPortIndexOutput, portMode[1]);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     EXPECT_EQ(timestampUslist.empty(), true);
     // set state to idle
     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
@@ -895,7 +894,8 @@
     changeStateIdletoExecute(omxNode, observer);
 
     // request EOS at the start
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 0U);
@@ -979,7 +979,8 @@
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
                            kPortIndexInput, kPortIndexOutput, portMode[1]);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 1U);
@@ -994,7 +995,8 @@
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
                            kPortIndexInput, kPortIndexOutput, portMode[1]);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     EXPECT_GE(framesReceived, 1U);
@@ -1077,7 +1079,8 @@
     eleStream.close();
     waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
                            kPortIndexInput, kPortIndexOutput, portMode[1]);
-    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode);
+    testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
+            portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
                kPortIndexOutput);
     framesReceived = 0;
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index e67f94f..2f00fbb 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -44,6 +44,8 @@
   { 0x20, 0x04, 0x02, 0x01, 0x00 }
 #define CORE_INIT_CMD \
     { 0x20, 0x01, 0x00 }
+#define CORE_INIT_CMD_NCI20 \
+    { 0x20, 0x01, 0x02, 0x00, 0x00 }
 #define INVALID_COMMAND \
   { 0x20, 0x00, 0x00 }
 
@@ -290,16 +292,23 @@
         // Wait for CORE_RESET_NTF
         res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
         EXPECT_TRUE(res.no_timeout);
+        cmd = CORE_INIT_CMD_NCI20;
+    } else {
+        cmd = CORE_INIT_CMD;
     }
-
-    cmd = CORE_INIT_CMD;
     data = cmd;
+
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_INIT_RSP
     res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
     EXPECT_TRUE(res.no_timeout);
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
-
+    if (nci_version == NCI_VERSION_2 && res.args->last_data_.size() > 13 &&
+        res.args->last_data_[13] == 0x00) {
+        // Wait for CORE_CONN_CREDITS_NTF
+        res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+        EXPECT_TRUE(res.no_timeout);
+    }
     // Send an Error Data Packet
     cmd = INVALID_COMMAND;
     data = cmd;
@@ -347,15 +356,23 @@
         // Wait for CORE_RESET_NTF
         res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
         EXPECT_TRUE(res.no_timeout);
+        cmd = CORE_INIT_CMD_NCI20;
+    } else {
+        cmd = CORE_INIT_CMD;
     }
-
-    cmd = CORE_INIT_CMD;
     data = cmd;
+
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_INIT_RSP
     res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
     EXPECT_TRUE(res.no_timeout);
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
+    if (nci_version == NCI_VERSION_2 && res.args->last_data_.size() > 13 &&
+        res.args->last_data_[13] == 0x00) {
+        // Wait for CORE_CONN_CREDITS_NTF
+        res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+        EXPECT_TRUE(res.no_timeout);
+    }
 
     cmd = CORE_CONN_CREATE_CMD;
     data = cmd;
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
index 5a3046d..4684e0f 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -100,7 +100,8 @@
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::INVALID_CALL_ID ||
-                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT || CheckOEMError());
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT || CheckOEMError() ||
+                    radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE);
     }
 }
 
@@ -225,6 +226,7 @@
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE ||
-                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT ||
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
 }
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index 466bea4..d93b176 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -397,7 +397,8 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::EMPTY_RECORD);
     }
 }
 
@@ -757,7 +758,8 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE || CheckGeneralError());
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
 
     /* Reset back to no carrier restriction */
@@ -771,8 +773,9 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE || CheckGeneralError());
-  }
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+    }
 }
 
 /*
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
index 0dc274a..da46e88 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
@@ -40,24 +40,6 @@
                     radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR);
     }
-
-    // Test with sending random string
-    serial = GetRandomSerialNumber();
-    content = "0";
-
-    radio->sendEnvelope(serial, content);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::NONE ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
-    }
 }
 
 /*
@@ -81,23 +63,6 @@
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
                     radioRsp->rspInfo.error == RadioError::NONE);
     }
-
-    serial = GetRandomSerialNumber();
-
-    // Test with sending random string
-    commandResponse = "0";
-
-    radio->sendTerminalResponseToSim(serial, commandResponse);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
-    }
 }
 
 /*
@@ -159,21 +124,4 @@
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
                     radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
-
-    // Test with sending random string
-    serial = GetRandomSerialNumber();
-    contents = "0";
-
-    radio->sendEnvelopeWithStatus(serial, contents);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
-                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
-    }
 }
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
index ad30e49..10f8f62 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <radio_hidl_hal_utils_v1_1.h>
+#include <vector>
 
 /*
  * Test IRadio.setSimCardPower() for the response returned.
@@ -111,4 +112,139 @@
                     radioRsp_v1_1->rspInfo.error == RadioError::SIM_ABSENT ||
                     radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
-}
\ No newline at end of file
+}
+
+/*
+ * Test IRadio.setCarrierInfoForImsiEncryption() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, setCarrierInfoForImsiEncryption) {
+    int serial = GetRandomSerialNumber();
+    ImsiEncryptionInfo imsiInfo;
+    imsiInfo.mcc = "310";
+    imsiInfo.mnc = "004";
+    imsiInfo.carrierKey = (std::vector<uint8_t>){1, 2, 3, 4, 5, 6};
+    imsiInfo.keyIdentifier = "Test";
+    imsiInfo.expirationTime = 20180101;
+
+    radio_v1_1->setCarrierInfoForImsiEncryption(serial, imsiInfo);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+    if (cardStatus.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::NONE ||
+                    radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+    }
+}
+
+/*
+ * Test IRadio.startKeepalive() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, startKeepalive) {
+    std::vector<KeepaliveRequest> requests = {
+        {
+            // Invalid IPv4 source address
+            KeepaliveType::NATT_IPV4,
+            {192, 168, 0 /*, 100*/},
+            1234,
+            {8, 8, 4, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid IPv4 destination address
+            KeepaliveType::NATT_IPV4,
+            {192, 168, 0, 100},
+            1234,
+            {8, 8, 4, 4, 1, 2, 3, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid Keepalive Type
+            static_cast<KeepaliveType>(-1),
+            {192, 168, 0, 100},
+            1234,
+            {8, 8, 4, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid IPv6 source address
+            KeepaliveType::NATT_IPV6,
+            {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+             0xBE, 0xEF, 0xBD},
+            1234,
+            {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+             0x88, 0x44},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid IPv6 destination address
+            KeepaliveType::NATT_IPV6,
+            {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+             0xBE, 0xEF},
+            1234,
+            {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+             0x88,
+             /*0x44*/},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid Context ID (cid), this should survive the initial
+            // range checking and fail in the modem data layer
+            KeepaliveType::NATT_IPV4,
+            {192, 168, 0, 100},
+            1234,
+            {8, 8, 4, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid Context ID (cid), this should survive the initial
+            // range checking and fail in the modem data layer
+            KeepaliveType::NATT_IPV6,
+            {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+             0xBE, 0xEF},
+            1234,
+            {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+             0x88, 0x44},
+            4500,
+            20000,
+            0xBAD,
+        }};
+
+    for (auto req = requests.begin(); req != requests.end(); req++) {
+        int serial = GetRandomSerialNumber();
+        radio_v1_1->startKeepalive(serial, *req);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+        ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+    }
+}
+
+/*
+ * Test IRadio.stopKeepalive() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, stopKeepalive) {
+    int serial = GetRandomSerialNumber();
+
+    radio_v1_1->stopKeepalive(serial, 0xBAD);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+    ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+}
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
index dd4f1ef..c797e35 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
+++ b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
@@ -53,6 +53,7 @@
     hidl_string imsi;
     IccIoResult iccIoResult;
     int channelId;
+    KeepaliveStatus keepaliveStatus;
 
     // Sms
     SendSmsResult sendSmsResult;
@@ -567,4 +568,4 @@
    public:
     virtual void SetUp() {}
     virtual void TearDown() {}
-};
\ No newline at end of file
+};
diff --git a/radio/1.1/vts/functional/radio_response.cpp b/radio/1.1/vts/functional/radio_response.cpp
index 37b80b1..400ef3c 100644
--- a/radio/1.1/vts/functional/radio_response.cpp
+++ b/radio/1.1/vts/functional/radio_response.cpp
@@ -659,7 +659,9 @@
 
 /* 1.1 Apis */
 Return<void> RadioResponse_v1_1::setCarrierInfoForImsiEncryptionResponse(
-    const RadioResponseInfo& /*info*/) {
+    const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_1.notify();
     return Void();
 }
 
@@ -681,11 +683,16 @@
     return Void();
 }
 
-Return<void> RadioResponse_v1_1::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
-                                                        const KeepaliveStatus& /*status*/) {
+Return<void> RadioResponse_v1_1::startKeepaliveResponse(const RadioResponseInfo& info,
+                                                        const KeepaliveStatus& status) {
+    rspInfo = info;
+    keepaliveStatus = status;
+    parent_v1_1.notify();
     return Void();
 }
 
-Return<void> RadioResponse_v1_1::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_1::stopKeepaliveResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_1.notify();
     return Void();
-}
\ No newline at end of file
+}
diff --git a/tetheroffload/Android.bp b/tetheroffload/Android.bp
index 4b50f11..f3c7021 100644
--- a/tetheroffload/Android.bp
+++ b/tetheroffload/Android.bp
@@ -1,5 +1,7 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "config/1.0",
+    "config/1.0/vts/functional",
     "control/1.0",
+    "control/1.0/vts/functional",
 ]
diff --git a/tetheroffload/config/1.0/vts/functional/Android.bp b/tetheroffload/config/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..2e720c6
--- /dev/null
+++ b/tetheroffload/config/1.0/vts/functional/Android.bp
@@ -0,0 +1,33 @@
+// 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_test {
+    name: "VtsHalTetheroffloadConfigV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalTetheroffloadConfigV1_0TargetTest.cpp"],
+    shared_libs: [
+        "android.hardware.tetheroffload.config@1.0",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
new file mode 100644
index 0000000..fc61e1c
--- /dev/null
+++ b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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 "VtsOffloadConfigV1_0TargetTest"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <set>
+
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::Return;
+using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
+using android::hardware::Void;
+using android::sp;
+
+#define ASSERT_TRUE_CALLBACK \
+    [&](bool success, const hidl_string& errMsg) { ASSERT_TRUE(success) << errMsg.c_str(); }
+
+#define ASSERT_FALSE_CALLBACK \
+    [&](bool success, const hidl_string& errMsg) { ASSERT_FALSE(success) << errMsg.c_str(); }
+
+const unsigned kFd1Groups = NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY;
+const unsigned kFd2Groups = NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY;
+
+inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
+    return reinterpret_cast<const sockaddr*>(nladdr);
+}
+
+int netlinkSocket(int protocol, unsigned groups) {
+    unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, protocol));
+    if (s.get() < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl bind_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (::bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) != 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl kernel_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (::connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+        return -errno;
+    }
+
+    return s.release();
+}
+
+int netlinkSocket(unsigned groups) {
+    return netlinkSocket(NETLINK_NETFILTER, groups);
+}
+
+class OffloadConfigHidlTest : public testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>();
+        ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
+    }
+
+    virtual void TearDown() override {}
+
+    sp<IOffloadConfig> config;
+};
+
+// Ensure handles can be set with correct socket options.
+TEST_F(OffloadConfigHidlTest, TestSetHandles) {
+    unique_fd fd1(netlinkSocket(kFd1Groups));
+    if (fd1.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+    nativeHandle1->data[0] = fd1.release();
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+    unique_fd fd2(netlinkSocket(kFd2Groups));
+    if (fd2.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+    nativeHandle2->data[0] = fd2.release();
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when both FDs are empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandleNone) {
+    native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+    native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when FD2 is empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandle1Only) {
+    unique_fd fd1(netlinkSocket(kFd1Groups));
+    if (fd1.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+    nativeHandle1->data[0] = fd1.release();
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+    native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when FD1 is empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandle2OnlyNotOk) {
+    native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+    unique_fd fd2(netlinkSocket(kFd2Groups));
+    if (fd2.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+    nativeHandle2->data[0] = fd2.release();
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGE("Test result with status=%d", status);
+    return status;
+}
diff --git a/tetheroffload/control/1.0/vts/functional/Android.bp b/tetheroffload/control/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..69fac6e
--- /dev/null
+++ b/tetheroffload/control/1.0/vts/functional/Android.bp
@@ -0,0 +1,34 @@
+// 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_test {
+    name: "VtsHalTetheroffloadControlV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalTetheroffloadControlV1_0TargetTest.cpp"],
+    shared_libs: [
+        "android.hardware.tetheroffload.config@1.0",
+        "android.hardware.tetheroffload.control@1.0",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
new file mode 100644
index 0000000..3d5cc81
--- /dev/null
+++ b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
@@ -0,0 +1,625 @@
+/*
+ * 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 "VtsOffloadControlV1_0TargetTest"
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+#include <android/hardware/tetheroffload/control/1.0/IOffloadControl.h>
+#include <android/hardware/tetheroffload/control/1.0/types.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <set>
+
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
+using android::hardware::tetheroffload::control::V1_0::IOffloadControl;
+using android::hardware::tetheroffload::control::V1_0::IPv4AddrPortPair;
+using android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;
+using android::hardware::tetheroffload::control::V1_0::OffloadCallbackEvent;
+using android::hardware::tetheroffload::control::V1_0::NatTimeoutUpdate;
+using android::hardware::tetheroffload::control::V1_0::NetworkProtocol;
+using android::hardware::Void;
+using android::sp;
+
+// We use #defines here so as to get local lamba captures and error message line numbers
+#define ASSERT_TRUE_CALLBACK                            \
+    [&](bool success, std::string errMsg) {             \
+        if (!success) {                                 \
+            ALOGI("Error message: %s", errMsg.c_str()); \
+        }                                               \
+        ASSERT_TRUE(success);                           \
+    }
+
+#define ASSERT_FALSE_CALLBACK                           \
+    [&](bool success, std::string errMsg) {             \
+        if (!success) {                                 \
+            ALOGI("Error message: %s", errMsg.c_str()); \
+        }                                               \
+        ASSERT_FALSE(success);                          \
+    }
+
+#define ASSERT_ZERO_BYTES_CALLBACK            \
+    [&](uint64_t rxBytes, uint64_t txBytes) { \
+        EXPECT_EQ(0ULL, rxBytes);             \
+        EXPECT_EQ(0ULL, txBytes);             \
+    }
+
+inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
+    return reinterpret_cast<const sockaddr*>(nladdr);
+}
+
+int conntrackSocket(unsigned groups) {
+    unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_NETFILTER));
+    if (s.get() < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl bind_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (::bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl kernel_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+        return -errno;
+    }
+
+    return s.release();
+}
+
+constexpr char kCallbackOnEvent[] = "onEvent";
+constexpr char kCallbackUpdateTimeout[] = "updateTimeout";
+
+class TetheringOffloadCallbackArgs {
+   public:
+    OffloadCallbackEvent last_event;
+    NatTimeoutUpdate last_params;
+};
+
+class OffloadControlHidlTestBase : public testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        setupConfigHal();
+        prepareControlHal();
+    }
+
+    virtual void TearDown() override { stopOffload(false); }
+
+    // The IOffloadConfig HAL is tested more thoroughly elsewhere. He we just
+    // setup everything correctly and verify basic readiness.
+    void setupConfigHal() {
+        config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>();
+        ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
+
+        unique_fd fd1(conntrackSocket(NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY));
+        if (fd1.get() < 0) {
+            ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+            FAIL();
+        }
+        native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+        nativeHandle1->data[0] = fd1.release();
+        hidl_handle h1 = hidl_handle(nativeHandle1);
+
+        unique_fd fd2(conntrackSocket(NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY));
+        if (fd2.get() < 0) {
+            ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+            FAIL();
+        }
+        native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+        nativeHandle2->data[0] = fd2.release();
+        hidl_handle h2 = hidl_handle(nativeHandle2);
+
+        const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    void prepareControlHal() {
+        control = testing::VtsHalHidlTargetTestBase::getService<IOffloadControl>();
+        ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
+
+        control_cb = new TetheringOffloadCallback();
+        ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback";
+    }
+
+    void initOffload(const bool expected_result) {
+        auto init_cb = [&](bool success, std::string errMsg) {
+            if (!success) {
+                ALOGI("Error message: %s", errMsg.c_str());
+            }
+            ASSERT_EQ(expected_result, success);
+        };
+        const Return<void> ret = control->initOffload(control_cb, init_cb);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    void setupControlHal() {
+        prepareControlHal();
+        initOffload(true);
+    }
+
+    void stopOffload(const bool expected_result) {
+        auto cb = [&](bool success, const hidl_string& errMsg) {
+            if (!success) {
+                ALOGI("Error message: %s", errMsg.c_str());
+            }
+            ASSERT_EQ(expected_result, success);
+        };
+        const Return<void> ret = control->stopOffload(cb);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    // Callback class for both events and NAT timeout updates.
+    class TetheringOffloadCallback
+        : public testing::VtsHalHidlTargetCallbackBase<TetheringOffloadCallbackArgs>,
+          public ITetheringOffloadCallback {
+       public:
+        TetheringOffloadCallback() = default;
+        virtual ~TetheringOffloadCallback() = default;
+
+        Return<void> onEvent(OffloadCallbackEvent event) override {
+            const TetheringOffloadCallbackArgs args{.last_event = event};
+            NotifyFromCallback(kCallbackOnEvent, args);
+            return Void();
+        };
+
+        Return<void> updateTimeout(const NatTimeoutUpdate& params) override {
+            const TetheringOffloadCallbackArgs args{.last_params = params};
+            NotifyFromCallback(kCallbackUpdateTimeout, args);
+            return Void();
+        };
+    };
+
+    sp<IOffloadConfig> config;
+    sp<IOffloadControl> control;
+    sp<TetheringOffloadCallback> control_cb;
+};
+
+// Call initOffload() multiple times. Check that non-first initOffload() calls return false.
+TEST_F(OffloadControlHidlTestBase, AdditionalInitsWithoutStopReturnFalse) {
+    initOffload(true);
+    initOffload(false);
+    initOffload(false);
+    initOffload(false);
+    stopOffload(true);  // balance out initOffload(true)
+}
+
+// Check that calling stopOffload() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, MultipleStopsWithoutInitReturnFalse) {
+    stopOffload(false);
+    stopOffload(false);
+    stopOffload(false);
+}
+
+// Check that calling stopOffload() after a complete init/stop cycle returns false.
+TEST_F(OffloadControlHidlTestBase, AdditionalStopsWithInitReturnFalse) {
+    initOffload(true);
+    stopOffload(true);  // balance out initOffload(true)
+    stopOffload(false);
+    stopOffload(false);
+}
+
+// Check that calling setLocalPrefixes() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, SetLocalPrefixesWithoutInitReturnsFalse) {
+    const vector<hidl_string> prefixes{hidl_string("2001:db8::/64")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling getForwardedStats() without first having called initOffload()
+// returns zero bytes statistics.
+TEST_F(OffloadControlHidlTestBase, GetForwardedStatsWithoutInitReturnsZeroValues) {
+    const hidl_string upstream("rmnet_data0");
+    const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling setDataLimit() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, SetDataLimitWithoutInitReturnsFalse) {
+    const hidl_string upstream("rmnet_data0");
+    const uint64_t limit = 5000ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling setUpstreamParameters() without first having called initOffload()
+// returns false.
+TEST_F(OffloadControlHidlTestBase, SetUpstreamParametersWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.0/24");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling addDownstream() with an IPv4 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, AddIPv4DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling addDownstream() with an IPv6 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, AddIPv6DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling removeDownstream() with an IPv4 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, RemoveIPv4DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling removeDownstream() with an IPv6 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, RemoveIPv6DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+class OffloadControlHidlTest : public OffloadControlHidlTestBase {
+   public:
+    virtual void SetUp() override {
+        setupConfigHal();
+        setupControlHal();
+    }
+
+    virtual void TearDown() override { stopOffload(true); }
+};
+
+/*
+ * Tests for IOffloadControl::setLocalPrefixes().
+ */
+
+// Test setLocalPrefixes() accepts an IPv4 address.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4AddressOk) {
+    const vector<hidl_string> prefixes{hidl_string("192.0.2.1")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() accepts an IPv6 address.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv6AddressOk) {
+    const vector<hidl_string> prefixes{hidl_string("fe80::1")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4v6PrefixesOk) {
+    const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("fe80::/64")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setLocalPrefixes() fails given empty input. There is always
+// a non-empty set of local prefixes; when all networking interfaces are down
+// we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesEmptyFails) {
+    const vector<hidl_string> prefixes{};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() fails on incorrectly formed input strings.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesInvalidFails) {
+    const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("invalid")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::getForwardedStats().
+ */
+
+// Test that getForwardedStats() for a non-existent upstream yields zero bytes statistics.
+TEST_F(OffloadControlHidlTest, GetForwardedStatsInvalidUpstreamIface) {
+    const hidl_string upstream("invalid");
+    const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, GetForwardedStatsDummyIface) {
+    const hidl_string upstream("rmnet_data0");
+    const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::setDataLimit().
+ */
+
+// Test that setDataLimit() for an empty interface name fails.
+TEST_F(OffloadControlHidlTest, SetDataLimitEmptyUpstreamIfaceFails) {
+    const hidl_string upstream("");
+    const uint64_t limit = 5000ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetDataLimitNonZeroOk) {
+    const hidl_string upstream("rmnet_data0");
+    const uint64_t limit = 5000ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetDataLimitZeroOk) {
+    const hidl_string upstream("rmnet_data0");
+    const uint64_t limit = 0ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::setUpstreamParameters().
+ */
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv6OnlyOk) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("");
+    const hidl_string v4Gw("");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:2")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr;
+    const hidl_string v4Gw;
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:3")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4OnlyOk) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4v6Ok) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8::2")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setUpstreamParameters() fails when all parameters are empty.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersEmptyFails) {
+    const hidl_string iface("");
+    const hidl_string v4Addr("");
+    const hidl_string v4Gw("");
+    const vector<hidl_string> v6Gws{};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setUpstreamParameters() fails when given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersBogusIfaceFails) {
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+        const hidl_string iface(bogus);
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 addresses.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4AddrFails) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    for (const auto& bogus : {"invalid", "192.0.2"}) {
+        SCOPED_TRACE(StringPrintf("v4addr='%s'", bogus));
+        const hidl_string v4Addr(bogus);
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 gateways.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    for (const auto& bogus : {"invalid", "192.0.2"}) {
+        SCOPED_TRACE(StringPrintf("v4gateway='%s'", bogus));
+        const hidl_string v4Gw(bogus);
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv6 gateways.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersBadIPv6GatewaysFail) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    for (const auto& bogus : {"", "invalid", "fe80::bogus", "192.0.2.66"}) {
+        SCOPED_TRACE(StringPrintf("v6gateway='%s'", bogus));
+        const vector<hidl_string> v6Gws{hidl_string("fe80::1"), hidl_string(bogus)};
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+/*
+ * Tests for IOffloadControl::addDownstream().
+ */
+
+// Test addDownstream() works given an IPv4 prefix.
+TEST_F(OffloadControlHidlTest, AddDownstreamIPv4) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() works given an IPv6 prefix.
+TEST_F(OffloadControlHidlTest, AddDownstreamIPv6) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() fails given all empty parameters.
+TEST_F(OffloadControlHidlTest, AddDownstreamEmptyFails) {
+    const hidl_string iface("");
+    const hidl_string prefix("");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() fails given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, AddDownstreamInvalidIfaceFails) {
+    const hidl_string prefix("192.0.2.0/24");
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+        const hidl_string iface(bogus);
+        const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test addDownstream() fails given unparseable prefix arguments.
+TEST_F(OffloadControlHidlTest, AddDownstreamBogusPrefixFails) {
+    const hidl_string iface("dummy0");
+    for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+        SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
+        const hidl_string prefix(bogus);
+        const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+/*
+ * Tests for IOffloadControl::removeDownstream().
+ */
+
+// Test removeDownstream() works given an IPv4 prefix.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv4) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() works given an IPv6 prefix.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv6) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() fails given all empty parameters.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamEmptyFails) {
+    const hidl_string iface("");
+    const hidl_string prefix("");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() fails given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusIfaceFails) {
+    const hidl_string prefix("192.0.2.0/24");
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+        const hidl_string iface(bogus);
+        const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test removeDownstream() fails given unparseable prefix arguments.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusPrefixFails) {
+    const hidl_string iface("dummy0");
+    for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+        SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
+        const hidl_string prefix(bogus);
+        const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGE("Test result with status=%d", status);
+    return status;
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
index e4382bc..0851cb2 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -206,5 +206,7 @@
 void stopWifi() {
     sp<IWifi> wifi = getWifi();
     ASSERT_NE(wifi, nullptr);
-    ASSERT_EQ(HIDL_INVOKE(wifi, stop).code, WifiStatusCode::SUCCESS);
+    const auto status = HIDL_INVOKE(wifi, stop);
+    ASSERT_TRUE((status.code == WifiStatusCode::SUCCESS) ||
+                (status.code == WifiStatusCode::ERROR_NOT_AVAILABLE));
 }
diff --git a/wifi/1.1/default/service.cpp b/wifi/1.1/default/service.cpp
index b3fcd50..b4aed6c 100644
--- a/wifi/1.1/default/service.cpp
+++ b/wifi/1.1/default/service.cpp
@@ -27,7 +27,7 @@
 int main(int /*argc*/, char** argv) {
   android::base::InitLogging(argv,
                              android::base::LogdLogger(android::base::SYSTEM));
-  LOG(INFO) << "Wifi Hal is starting up...";
+  LOG(INFO) << "Wifi Hal is booting up...";
 
   configureRpcThreadpool(1, true /* callerWillJoin */);
 
diff --git a/wifi/1.1/default/wifi.cpp b/wifi/1.1/default/wifi.cpp
index fe4f642..8456b90 100644
--- a/wifi/1.1/default/wifi.cpp
+++ b/wifi/1.1/default/wifi.cpp
@@ -108,14 +108,15 @@
         LOG(ERROR) << "Failed to invoke onStart callback";
       };
     }
+    LOG(INFO) << "Wifi HAL started";
   } else {
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
       if (!callback->onFailure(wifi_status).isOk()) {
         LOG(ERROR) << "Failed to invoke onFailure callback";
       }
     }
+    LOG(ERROR) << "Wifi HAL start failed";
   }
-  LOG(INFO) << "Wifi HAL started";
   return wifi_status;
 }
 
@@ -139,14 +140,15 @@
         LOG(ERROR) << "Failed to invoke onStop callback";
       };
     }
+    LOG(INFO) << "Wifi HAL stopped";
   } else {
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
       if (!callback->onFailure(wifi_status).isOk()) {
         LOG(ERROR) << "Failed to invoke onFailure callback";
       }
     }
+    LOG(ERROR) << "Wifi HAL stop failed";
   }
-  LOG(INFO) << "Wifi HAL stopped";
   return wifi_status;
 }
 
diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
index 55f5a87..90c36dd 100644
--- a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
+++ b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
@@ -32,6 +32,8 @@
 using ::android::hardware::wifi::offload::V1_0::IOffloadCallback;
 using ::android::hardware::wifi::offload::V1_0::ScanResult;
 using ::android::hardware::wifi::offload::V1_0::ScanParam;
+using ::android::hardware::wifi::offload::V1_0::Ssid;
+using ::android::hardware::wifi::offload::V1_0::NetworkInfo;
 using ::android::hardware::wifi::offload::V1_0::ScanFilter;
 using ::android::hardware::wifi::offload::V1_0::ScanStats;
 using ::android::hardware::wifi::offload::V1_0::OffloadStatus;
@@ -45,7 +47,8 @@
 constexpr char kOffloadCallbackSendError[] = "onError";
 
 namespace {
-const uint8_t kSsid[] = {'G', 'o', 'o', 'g', 'l', 'e'};
+const uint8_t kSsid1[] = {'G', 'o', 'o', 'g', 'l', 'e'};
+const uint8_t kSsid2[] = {'X', 'f', 'i', 'n', 'i', 't', 'y'};
 const uint8_t kBssid[6] = {0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b};
 const int16_t kRssi = -60;
 const uint32_t kFrequency = 2412;
@@ -53,6 +56,10 @@
 const uint64_t kTsf = 0;
 const uint16_t kCapability = 0;
 const uint8_t kNetworkFlags = 0;
+const uint32_t kFrequency1 = 2412;
+const uint32_t kFrequency2 = 2437;
+const uint32_t kDisconnectedModeScanIntervalMs = 5000;
+const int16_t kRssiThreshold = -76;
 }
 
 class OffloadCallbackArgs {
@@ -133,7 +140,28 @@
  */
 TEST_F(WifiOffloadHidlTest, configureScans) {
     ScanParam* pScanParam = new ScanParam();
+    std::vector<uint32_t> frequencyList = {kFrequency1, kFrequency2};
+    pScanParam->disconnectedModeScanIntervalMs =
+        kDisconnectedModeScanIntervalMs;
+    pScanParam->frequencyList = frequencyList;
+    std::vector<Ssid> ssidList;
+    std::vector<std::vector<uint8_t>> ssids{kSsid1, kSsid2};
+    for (const auto& ssid : ssids) {
+        Ssid tmp = ssid;
+        ssidList.push_back(tmp);
+    }
+    pScanParam->ssidList = ssidList;
     ScanFilter* pScanFilter = new ScanFilter();
+    pScanFilter->rssiThreshold = kRssiThreshold;
+    std::vector<std::vector<uint8_t>> match_ssids{kSsid1, kSsid2};
+    std::vector<uint8_t> security_flags{kNetworkFlags, kNetworkFlags};
+    std::vector<NetworkInfo> preferredNetworksList;
+    for (size_t i = 0; i < security_flags.size(); i++) {
+        NetworkInfo nwInfo;
+        nwInfo.ssid = match_ssids[i];
+        nwInfo.flags = security_flags[i];
+        preferredNetworksList.push_back(nwInfo);
+    }
     const auto& result =
         HIDL_INVOKE(wifi_offload_, configureScans, *pScanParam, *pScanFilter);
     ASSERT_EQ(OffloadStatusCode::OK, result.code);
@@ -154,7 +182,7 @@
 TEST_F(WifiOffloadHidlTest, getScanResults) {
     wifi_offload_->setEventCallback(wifi_offload_cb_);
     std::vector<ScanResult> scan_results;
-    std::vector<uint8_t> ssid(kSsid, kSsid + sizeof(kSsid));
+    std::vector<uint8_t> ssid(kSsid1, kSsid1 + sizeof(kSsid1));
     ScanResult scan_result;
     scan_result.tsf = kTsf;
     scan_result.rssi = kRssi;