Merge "audio: fix mistake in AudioDevice enum"
diff --git a/audio/2.0/vts/functional/Android.bp b/audio/2.0/vts/functional/Android.bp
index 02f9330..f5ab76f 100644
--- a/audio/2.0/vts/functional/Android.bp
+++ b/audio/2.0/vts/functional/Android.bp
@@ -22,6 +22,7 @@
         "libbase",
         "liblog",
         "libhidlbase",
+        "libhidltransport",
         "libutils",
         "libcutils",
         "android.hardware.audio@2.0",
diff --git a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index e50b912..6270c9c 100644
--- a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -50,6 +50,7 @@
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::audio::V2_0::AudioDrain;
 using ::android::hardware::audio::V2_0::DeviceAddress;
 using ::android::hardware::audio::V2_0::IDevice;
 using ::android::hardware::audio::V2_0::IPrimaryDevice;
@@ -57,9 +58,11 @@
 using ::android::hardware::audio::V2_0::IDevicesFactory;
 using ::android::hardware::audio::V2_0::IStream;
 using ::android::hardware::audio::V2_0::IStreamIn;
+using ::android::hardware::audio::V2_0::TimeSpec;
 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::IStreamOutCallback;
 using ::android::hardware::audio::V2_0::MmapBufferInfo;
 using ::android::hardware::audio::V2_0::MmapPosition;
 using ::android::hardware::audio::V2_0::ParameterValue;
@@ -790,9 +793,9 @@
                checkGetParameter(stream.get(), {"Non existing key"} /* keys */,
                                  {Result::INVALID_ARGUMENTS}))
 
-static vector<Result> okOrNotSupported = {Result::OK, Result::INVALID_ARGUMENTS};
+static vector<Result> okOrInvalidArguments = {Result::OK, Result::INVALID_ARGUMENTS};
 TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
-               ASSERT_RESULT(okOrNotSupported, stream->setParameters({})))
+               ASSERT_RESULT(okOrInvalidArguments, stream->setParameters({})))
 
 TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
                ASSERT_RESULT(Result::INVALID_ARGUMENTS,
@@ -921,6 +924,183 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
+///////////////////////////////// StreamIn ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+TEST_P(OutputStreamTest, getLatency) {
+    doc::test("Make sure latency is over 0");
+    auto result = stream->getLatency();
+    ASSERT_TRUE(result.isOk());
+    ASSERT_GT(result, 0U);
+}
+
+TEST_P(OutputStreamTest, setVolume) {
+    doc::test("Try to set the output volume");
+    auto result = stream->setVolume(1, 1);
+    ASSERT_TRUE(result.isOk());
+    if (result == Result::NOT_SUPPORTED) {
+        doc::partialTest("setVolume is not supported");
+        return;
+    }
+    testUnitaryGain([this](float volume) { return stream->setVolume(volume, volume); });
+}
+
+static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32_t framesCount) {
+    Result res;
+    // Ignore output parameters as the call should fail
+    ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
+                                        [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
+    EXPECT_RESULT(invalidArgsOrNotSupported, res);
+}
+
+TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
+    doc::test("Preparing a stream for writing with a 2^32 sized buffer should fail");
+    testPrepareForWriting(stream.get(), 1, std::numeric_limits<uint32_t>::max());
+}
+
+TEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) {
+    doc::test("Preparing a stream for writing with a overflowing sized buffer should fail");
+    auto uintMax = std::numeric_limits<uint32_t>::max();
+    testPrepareForWriting(stream.get(), uintMax, uintMax);
+}
+
+struct Capability {
+    Capability(IStreamOut* stream) {
+        EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
+        auto ret = stream->supportsDrain();
+        EXPECT_TRUE(ret.isOk());
+        if (ret.isOk()) {
+            drain = ret;
+        }
+    }
+    bool pause = false;
+    bool resume = false;
+    bool drain = false;
+};
+
+TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
+    Capability(stream.get());
+}
+
+TEST_P(OutputStreamTest, GetRenderPosition) {
+    uint32_t dspFrames;
+    ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
+    if (res == Result::NOT_SUPPORTED) {
+        doc::partialTest("getRenderPosition is not supported");
+        return;
+    }
+    ASSERT_OK(res);
+    ASSERT_EQ(0U, dspFrames);
+}
+
+TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
+    uint64_t timestampUs;
+    ASSERT_OK(stream->getRenderPosition(returnIn(res, timestampUs)));
+    if (res == Result::NOT_SUPPORTED) {
+        doc::partialTest("getRenderPosition is not supported");
+        return;
+    }
+    ASSERT_OK(res);
+    ASSERT_EQ(0U, timestampUs);
+}
+
+/** Stub implementation of out stream callback. */
+class MockOutCallbacks : public IStreamOutCallback {
+    Return<void> onWriteReady() override { return {}; }
+    Return<void> onDrainReady() override { return {}; }
+    Return<void> onError() override { return {}; }
+};
+
+static bool isAsyncModeSupported(IStreamOut *stream) {
+    auto res = stream->setCallback(new MockOutCallbacks);
+    stream->clearCallback(); // try to restore the no callback state, ignore any error
+    auto okOrNotSupported = { Result::OK, Result::NOT_SUPPORTED };
+    EXPECT_RESULT(okOrNotSupported, res);
+    return res.isOk() ? res == Result::OK : false;
+}
+
+TEST_P(OutputStreamTest, SetCallback) {
+    if (!isAsyncModeSupported(stream.get())) {
+        doc::partialTest("The stream does not support async operations");
+        return;
+    }
+    ASSERT_OK(stream->setCallback(new MockOutCallbacks));
+    ASSERT_OK(stream->setCallback(new MockOutCallbacks));
+}
+
+TEST_P(OutputStreamTest, clearCallback) {
+    if (!isAsyncModeSupported(stream.get())) {
+        doc::partialTest("The stream does not support async operations");
+        return;
+    }
+    // TODO: Clarify if clearing a non existing callback should fail
+    ASSERT_OK(stream->setCallback(new MockOutCallbacks));
+    ASSERT_OK(stream->clearCallback());
+}
+
+TEST_P(OutputStreamTest, Resume) {
+    if (!Capability(stream.get()).resume) {
+        doc::partialTest("The output stream does not support resume");
+        return;
+    }
+    ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
+}
+
+TEST_P(OutputStreamTest, Pause) {
+    if (!Capability(stream.get()).pause) {
+        doc::partialTest("The output stream does not support pause");
+        return;
+    }
+    ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
+}
+
+static void testDrain(IStreamOut *stream, AudioDrain type) {
+    if (!Capability(stream).drain) {
+        doc::partialTest("The output stream does not support pause");
+        return;
+    }
+    ASSERT_RESULT(Result::OK, stream->drain(type));
+}
+
+TEST_P(OutputStreamTest, DrainAll) {
+    testDrain(stream.get(), AudioDrain::ALL);
+}
+
+TEST_P(OutputStreamTest, DrainEarlyNotify) {
+    testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
+}
+
+TEST_P(OutputStreamTest, FlushStop) {
+    ASSERT_OK(stream->flush());
+}
+
+/** Return thee difference in us of two TimeSpec */
+uint64_t operator-(TimeSpec left, TimeSpec right) {
+    auto toMicroSec = [](auto ts) { return ts.tvSec * 1e+6 + ts.tvNSec / 1e+3; };
+    return toMicroSec(left) - toMicroSec(right);
+}
+
+TEST_P(OutputStreamTest, GetPresentationPositionStop) {
+    uint64_t frames;
+    TimeSpec mesureTS;
+    ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
+    if (res == Result::NOT_SUPPORTED) {
+        doc::partialTest("getpresentationPosition is not supported");
+        return;
+    }
+    ASSERT_EQ(0U, frames);
+
+    struct timespec currentTS;
+    ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &currentTS)) << errno;
+
+    auto toMicroSec = [](uint64_t sec, auto nsec) { return sec * 1e+6 + nsec / 1e+3; };
+    auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec);
+    auto mesureTime = toMicroSec(mesureTS.tvSec, mesureTS.tvNSec);
+    ASSERT_PRED2([](auto c, auto m){ return  c - m < 1e+6; }, currentTime, mesureTime);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// PrimaryDevice ////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
diff --git a/audio/2.0/vts/functional/utility/AssertOk.h b/audio/2.0/vts/functional/utility/AssertOk.h
index 39c9a1d..10b088c 100644
--- a/audio/2.0/vts/functional/utility/AssertOk.h
+++ b/audio/2.0/vts/functional/utility/AssertOk.h
@@ -29,13 +29,13 @@
     ASSERT_EQ(expected, result);
 }
 
-inline void assertResult(Result expected, Return<Result> ret) {
+inline void assertResult(Result expected, const Return<Result> &ret) {
     ASSERT_TRUE(ret.isOk());
     Result result = ret;
     assertResult(expected, result);
 }
 
-inline void assertResult(std::vector<Result> expected, Result result) {
+inline void assertResult(const std::vector<Result> &expected, Result result) {
     if (std::find(expected.begin(), expected.end(), result) != expected.end()) {
         return; // result is in expected
     }
@@ -43,13 +43,13 @@
            << " to be one of " << ::testing::PrintToString(expected);
 }
 
-inline void assertResult(std::vector<Result> expected, Return<Result> ret) {
+inline void assertResult(const std::vector<Result> &expected, const Return<Result> &ret) {
     ASSERT_TRUE(ret.isOk());
     Result result = ret;
     assertResult(expected, result);
 }
 
-inline void assertOk(Return<void> ret) {
+inline void assertOk(const Return<void> &ret) {
     ASSERT_TRUE(ret.isOk());
 }
 
@@ -57,8 +57,8 @@
     assertResult(Result::OK, result);
 }
 
-inline void assertOk(Return<Result> ret) {
-    assertResult(Result::OK, std::move(ret));
+inline void assertOk(const Return<Result> &ret) {
+    assertResult(Result::OK, ret);
 }
 
 }
@@ -68,4 +68,4 @@
 #define EXPECT_OK(ret) EXPECT_NO_FATAL_FAILURE(detail::assertOk(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))
+#define EXPECT_RESULT(expected, ret) EXPECT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
diff --git a/automotive/vehicle/2.1/Android.bp b/automotive/vehicle/2.1/Android.bp
index dcf395c..cf4d8b0 100644
--- a/automotive/vehicle/2.1/Android.bp
+++ b/automotive/vehicle/2.1/Android.bp
@@ -51,6 +51,7 @@
         "libutils",
         "libcutils",
         "android.hardware.automotive.vehicle@2.0",
+        "android.hidl.base@1.0",
     ],
     export_shared_lib_headers: [
         "libhidlbase",
@@ -58,5 +59,6 @@
         "libhwbinder",
         "libutils",
         "android.hardware.automotive.vehicle@2.0",
+        "android.hidl.base@1.0",
     ],
 }
diff --git a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
index b106481..5b00675 100644
--- a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
+++ b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
@@ -264,27 +264,35 @@
         case FINGERPRINT_ERROR: {
                 int32_t vendorCode = 0;
                 FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
-                thisPtr->mClientCallback->onError(devId, result, vendorCode);
+                if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
+                    ALOGE("failed to invoke fingerprint onError callback");
+                }
             }
             break;
         case FINGERPRINT_ACQUIRED: {
                 int32_t vendorCode = 0;
                 FingerprintAcquiredInfo result =
                     VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
-                thisPtr->mClientCallback->onAcquired(devId, result, vendorCode);
+                if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) {
+                    ALOGE("failed to invoke fingerprint onAcquired callback");
+                }
             }
             break;
         case FINGERPRINT_TEMPLATE_ENROLLING:
-            thisPtr->mClientCallback->onEnrollResult(devId,
-                msg->data.enroll.finger.fid,
-                msg->data.enroll.finger.gid,
-                msg->data.enroll.samples_remaining);
+            if (!thisPtr->mClientCallback->onEnrollResult(devId,
+                    msg->data.enroll.finger.fid,
+                    msg->data.enroll.finger.gid,
+                    msg->data.enroll.samples_remaining).isOk()) {
+                ALOGE("failed to invoke fingerprint onEnrollResult callback");
+            }
             break;
         case FINGERPRINT_TEMPLATE_REMOVED:
-            thisPtr->mClientCallback->onRemoved(devId,
-                msg->data.removed.finger.fid,
-                msg->data.removed.finger.gid,
-                msg->data.removed.remaining_templates);
+            if (!thisPtr->mClientCallback->onRemoved(devId,
+                    msg->data.removed.finger.fid,
+                    msg->data.removed.finger.gid,
+                    msg->data.removed.remaining_templates).isOk()) {
+                ALOGE("failed to invoke fingerprint onRemoved callback");
+            }
             break;
         case FINGERPRINT_AUTHENTICATED:
             if (msg->data.authenticated.finger.fid != 0) {
@@ -292,23 +300,29 @@
                     reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
                 const hidl_vec<uint8_t> token(
                     std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
-                thisPtr->mClientCallback->onAuthenticated(devId,
-                    msg->data.authenticated.finger.fid,
-                    msg->data.authenticated.finger.gid,
-                    token);
+                if (!thisPtr->mClientCallback->onAuthenticated(devId,
+                        msg->data.authenticated.finger.fid,
+                        msg->data.authenticated.finger.gid,
+                        token).isOk()) {
+                    ALOGE("failed to invoke fingerprint onAuthenticated callback");
+                }
             } else {
                 // Not a recognized fingerprint
-                thisPtr->mClientCallback->onAuthenticated(devId,
-                    msg->data.authenticated.finger.fid,
-                    msg->data.authenticated.finger.gid,
-                    hidl_vec<uint8_t>());
+                if (!thisPtr->mClientCallback->onAuthenticated(devId,
+                        msg->data.authenticated.finger.fid,
+                        msg->data.authenticated.finger.gid,
+                        hidl_vec<uint8_t>()).isOk()) {
+                    ALOGE("failed to invoke fingerprint onAuthenticated callback");
+                }
             }
             break;
         case FINGERPRINT_TEMPLATE_ENUMERATING:
-            thisPtr->mClientCallback->onEnumerate(devId,
-                msg->data.enumerated.finger.fid,
-                msg->data.enumerated.finger.gid,
-                msg->data.enumerated.remaining_templates);
+            if (!thisPtr->mClientCallback->onEnumerate(devId,
+                    msg->data.enumerated.finger.fid,
+                    msg->data.enumerated.finger.gid,
+                    msg->data.enumerated.remaining_templates).isOk()) {
+                ALOGE("failed to invoke fingerprint onEnumerate callback");
+            }
             break;
     }
 }
diff --git a/biometrics/fingerprint/2.1/default/service.cpp b/biometrics/fingerprint/2.1/default/service.cpp
index d6b91c6..1697c07 100644
--- a/biometrics/fingerprint/2.1/default/service.cpp
+++ b/biometrics/fingerprint/2.1/default/service.cpp
@@ -35,7 +35,7 @@
     configureRpcThreadpool(1, true /*callerWillJoin*/);
 
     if (bio != nullptr) {
-        bio->registerAsService("fingerprint_hal");
+        bio->registerAsService();
     } else {
         ALOGE("Can't create instance of BiometricsFingerprint, nullptr");
     }
diff --git a/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp b/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
index c07c3e3..cd38f2e 100644
--- a/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
+++ b/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
@@ -15,7 +15,6 @@
  */
 
 #define LOG_TAG "fingerprint_hidl_hal_test"
-#define SERVICE_NAME "fingerprint_hal"
 
 #include <android-base/logging.h>
 #include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
@@ -123,7 +122,7 @@
     FingerprintHidlTest (): mCallbackCalled(false) {}
 
     virtual void SetUp() override {
-        mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFingerprint>(SERVICE_NAME);
+        mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFingerprint>();
 
         ASSERT_NE(mService, nullptr);
         clearErr();
diff --git a/bluetooth/1.0/default/bluetooth_hci.cc b/bluetooth/1.0/default/bluetooth_hci.cc
index 5a282bf..fec5b81 100644
--- a/bluetooth/1.0/default/bluetooth_hci.cc
+++ b/bluetooth/1.0/default/bluetooth_hci.cc
@@ -30,6 +30,19 @@
 static const uint8_t HCI_DATA_TYPE_ACL = 2;
 static const uint8_t HCI_DATA_TYPE_SCO = 3;
 
+class BluetoothDeathRecipient : public hidl_death_recipient {
+ public:
+  BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
+
+  virtual void serviceDied(
+      uint64_t /*cookie*/,
+      const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+    ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
+    mHci->close();
+  }
+  sp<IBluetoothHci> mHci;
+};
+
 BluetoothHci::BluetoothHci()
     : deathRecipient(new BluetoothDeathRecipient(this)) {}
 
@@ -41,19 +54,37 @@
 
   bool rc = VendorInterface::Initialize(
       [this](bool status) {
-        event_cb_->initializationComplete(
+        auto hidl_status = event_cb_->initializationComplete(
             status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
+        if (!hidl_status.isOk()) {
+          ALOGE("VendorInterface -> Unable to call initializationComplete()");
+        }
       },
       [this](const hidl_vec<uint8_t>& packet) {
-        event_cb_->hciEventReceived(packet);
+        auto hidl_status = event_cb_->hciEventReceived(packet);
+        if (!hidl_status.isOk()) {
+          ALOGE("VendorInterface -> Unable to call hciEventReceived()");
+        }
       },
       [this](const hidl_vec<uint8_t>& packet) {
-        event_cb_->aclDataReceived(packet);
+        auto hidl_status = event_cb_->aclDataReceived(packet);
+        if (!hidl_status.isOk()) {
+          ALOGE("VendorInterface -> Unable to call aclDataReceived()");
+        }
       },
       [this](const hidl_vec<uint8_t>& packet) {
-        event_cb_->scoDataReceived(packet);
+        auto hidl_status = event_cb_->scoDataReceived(packet);
+        if (!hidl_status.isOk()) {
+          ALOGE("VendorInterface -> Unable to call scoDataReceived()");
+        }
       });
-  if (!rc) event_cb_->initializationComplete(Status::INITIALIZATION_ERROR);
+  if (!rc) {
+    auto hidl_status =
+        event_cb_->initializationComplete(Status::INITIALIZATION_ERROR);
+    if (!hidl_status.isOk()) {
+      ALOGE("VendorInterface -> Unable to call initializationComplete(ERR)");
+    }
+  }
   return Void();
 }
 
diff --git a/bluetooth/1.0/default/bluetooth_hci.h b/bluetooth/1.0/default/bluetooth_hci.h
index 67d6c37..4f92231 100644
--- a/bluetooth/1.0/default/bluetooth_hci.h
+++ b/bluetooth/1.0/default/bluetooth_hci.h
@@ -30,16 +30,7 @@
 using ::android::hardware::Return;
 using ::android::hardware::hidl_vec;
 
-struct BluetoothDeathRecipient : hidl_death_recipient {
-  BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
-
-  virtual void serviceDied(
-      uint64_t /*cookie*/,
-      const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
-    mHci->close();
-  }
-  sp<IBluetoothHci> mHci;
-};
+class BluetoothDeathRecipient;
 
 class BluetoothHci : public IBluetoothHci {
  public:
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index e6575b0..68cac5f 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -265,6 +265,13 @@
 }
 
 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/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
index 74911f0..4ec19c7 100644
--- a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
+++ b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
@@ -33,7 +33,6 @@
 using ::android::Mutex;
 using ::android::Condition;
 using ::android::hardware::Return;
-using ::android::hardware::Status;
 using ::android::hardware::Void;
 using ::android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory;
 using ::android::hardware::broadcastradio::V1_0::IBroadcastRadio;
@@ -455,6 +454,7 @@
  *  - the HAL implements the method
  *  - the method returns 0 (no error)
  *  - the tuned callback is received within kTuneCallbacktimeoutNs ns
+ *  - skipping sub-channel or not does not fail the call
  */
 TEST_F(BroadcastRadioHidlTest, Scan) {
     ASSERT_EQ(true, openTuner());
@@ -468,7 +468,7 @@
 
     // test scan DOWN
     mCallbackCalled = false;
-    hidlResult = mTuner->scan(Direction::DOWN, true);
+    hidlResult = mTuner->scan(Direction::DOWN, false);
     EXPECT_TRUE(hidlResult.isOk());
     EXPECT_EQ(Result::OK, hidlResult);
     EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
@@ -481,13 +481,14 @@
  *  - the HAL implements the method
  *  - the method returns 0 (no error)
  *  - the tuned callback is received within kTuneCallbacktimeoutNs ns
+ *  - skipping sub-channel or not does not fail the call
  */
 TEST_F(BroadcastRadioHidlTest, Step) {
     ASSERT_EQ(true, openTuner());
     ASSERT_TRUE(checkAntenna());
     // test step UP
     mCallbackCalled = false;
-    Return<Result> hidlResult = mTuner->step(Direction::UP, true);
+    Return<Result> hidlResult = mTuner->step(Direction::UP, false);
     EXPECT_TRUE(hidlResult.isOk());
     EXPECT_EQ(Result::OK, hidlResult);
     EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
diff --git a/broadcastradio/1.1/Android.bp b/broadcastradio/1.1/Android.bp
index c9a8b10..570d1ae 100644
--- a/broadcastradio/1.1/Android.bp
+++ b/broadcastradio/1.1/Android.bp
@@ -65,6 +65,7 @@
         "libutils",
         "libcutils",
         "android.hardware.broadcastradio@1.0",
+        "android.hidl.base@1.0",
     ],
     export_shared_lib_headers: [
         "libhidlbase",
@@ -72,5 +73,6 @@
         "libhwbinder",
         "libutils",
         "android.hardware.broadcastradio@1.0",
+        "android.hidl.base@1.0",
     ],
 }
diff --git a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
index aad01f6..a29f6dc 100644
--- a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
+++ b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
@@ -35,7 +35,6 @@
 using ::android::Mutex;
 using ::android::Condition;
 using ::android::hardware::Return;
-using ::android::hardware::Status;
 using ::android::hardware::Void;
 using ::android::hardware::broadcastradio::V1_0::BandConfig;
 using ::android::hardware::broadcastradio::V1_0::Class;
diff --git a/camera/device/3.2/ICameraDeviceCallback.hal b/camera/device/3.2/ICameraDeviceCallback.hal
index 753d085..bf51da2 100644
--- a/camera/device/3.2/ICameraDeviceCallback.hal
+++ b/camera/device/3.2/ICameraDeviceCallback.hal
@@ -35,7 +35,8 @@
     /**
      * processCaptureResult:
      *
-     * Send results from a completed capture to the framework.
+     * Send results from one or more completed or partially completed captures
+     * to the framework.
      * processCaptureResult() may be invoked multiple times by the HAL in
      * response to a single capture request. This allows, for example, the
      * metadata and low-resolution buffers to be returned in one call, and
@@ -61,11 +62,14 @@
      * acceptable and expected that the buffer for request 5 for stream A may be
      * returned after the buffer for request 6 for stream B is. And it is
      * acceptable that the result metadata for request 6 for stream B is
-     * returned before the buffer for request 5 for stream A is.
+     * returned before the buffer for request 5 for stream A is. If multiple
+     * capture results are included in a single call, camera framework must
+     * process results sequentially from lower index to higher index, as if
+     * these results were sent to camera framework one by one, from lower index
+     * to higher index.
      *
      * The HAL retains ownership of result structure, which only needs to be
-     * valid to access during this call. The framework must copy whatever it
-     * needs before this call returns.
+     * valid to access during this call.
      *
      * The output buffers do not need to be filled yet; the framework must wait
      * on the stream buffer release sync fence before reading the buffer
@@ -93,20 +97,23 @@
      *
      * Performance requirements:
      *
-     * This is a non-blocking call. The framework must return this call in 5ms.
+     * This is a non-blocking call. The framework must handle each CaptureResult
+     * within 5ms.
      *
      * The pipeline latency (see S7 for definition) should be less than or equal to
      * 4 frame intervals, and must be less than or equal to 8 frame intervals.
      *
      */
-    processCaptureResult(CaptureResult result);
+    processCaptureResult(vec<CaptureResult> results);
 
     /**
      * notify:
      *
      * Asynchronous notification callback from the HAL, fired for various
      * reasons. Only for information independent of frame capture, or that
-     * require specific timing.
+     * require specific timing. Multiple messages may be sent in one call; a
+     * message with a higher index must be considered to have occurred after a
+     * message with a lower index.
      *
      * Multiple threads may call notify() simultaneously.
      *
@@ -119,8 +126,8 @@
      * ------------------------------------------------------------------------
      * Performance requirements:
      *
-     * This is a non-blocking call. The framework must return this call in 5ms.
+     * This is a non-blocking call. The framework must handle each message in 5ms.
      */
-    notify(NotifyMsg msg);
+    notify(vec<NotifyMsg> msgs);
 
 };
diff --git a/camera/device/3.2/ICameraDeviceSession.hal b/camera/device/3.2/ICameraDeviceSession.hal
index e92d756..d8d3177 100644
--- a/camera/device/3.2/ICameraDeviceSession.hal
+++ b/camera/device/3.2/ICameraDeviceSession.hal
@@ -171,14 +171,16 @@
     /**
      * processCaptureRequest:
      *
-     * Send a new capture request to the HAL. The HAL must not return from
-     * this call until it is ready to accept the next request to process. Only
-     * one call to processCaptureRequest() must be made at a time by the
-     * framework, and the calls must all be from the same thread. The next call
-     * to processCaptureRequest() must be made as soon as a new request and
-     * its associated buffers are available. In a normal preview scenario, this
-     * means the function is generally called again by the framework almost
-     * instantly.
+     * Send a list of capture requests to the HAL. The HAL must not return from
+     * this call until it is ready to accept the next set of requests to
+     * process. Only one call to processCaptureRequest() must be made at a time
+     * by the framework, and the calls must all be from the same thread. The
+     * next call to processCaptureRequest() must be made as soon as a new
+     * request and its associated buffers are available. In a normal preview
+     * scenario, this means the function is generally called again by the
+     * framework almost instantly. If more than one request is provided by the
+     * client, the HAL must process the requests in order of lowest index to
+     * highest index.
      *
      * The actual request processing is asynchronous, with the results of
      * capture being returned by the HAL through the processCaptureResult()
@@ -229,10 +231,14 @@
      *         If the camera device has encountered a serious error. After this
      *         error is returned, only the close() method can be successfully
      *         called by the framework.
+     * @return numRequestProcessed Number of requests successfully processed by
+     *     camera HAL. When status is OK, this must be equal to the size of
+     *     requests. When the call fails, this number is the number of requests
+     *     that HAL processed successfully before HAL runs into an error.
      *
      */
-    processCaptureRequest(CaptureRequest request)
-            generates (Status status);
+    processCaptureRequest(vec<CaptureRequest> requests)
+            generates (Status status, uint32_t numRequestProcessed);
 
     /**
      * flush:
diff --git a/camera/device/3.2/default/CameraDevice.cpp b/camera/device/3.2/default/CameraDevice.cpp
index 0a457ad..a742335 100644
--- a/camera/device/3.2/default/CameraDevice.cpp
+++ b/camera/device/3.2/default/CameraDevice.cpp
@@ -229,7 +229,18 @@
             return Void();
         }
 
-        session = new CameraDeviceSession(device, callback);
+        struct camera_info info;
+        res = mModule->getCameraInfo(mCameraIdInt, &info);
+        if (res != OK) {
+            ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
+            device->common.close(&device->common);
+            mLock.unlock();
+            _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
+            return Void();
+        }
+
+        session = new CameraDeviceSession(
+                device, info.static_camera_characteristics, callback);
         if (session == nullptr) {
             ALOGE("%s: camera device session allocation failed", __FUNCTION__);
             mLock.unlock();
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index ae5d576..fb1d1ff 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "CamDevSession@3.2-impl"
 #include <android/log.h>
 
+#include <set>
 #include <utils/Trace.h>
 #include <hardware/gralloc.h>
 #include <hardware/gralloc1.h>
@@ -30,12 +31,25 @@
 namespace implementation {
 
 HandleImporter& CameraDeviceSession::sHandleImporter = HandleImporter::getInstance();
+const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
 
 CameraDeviceSession::CameraDeviceSession(
-    camera3_device_t* device, const sp<ICameraDeviceCallback>& callback) :
+    camera3_device_t* device,
+    const camera_metadata_t* deviceInfo,
+    const sp<ICameraDeviceCallback>& callback) :
         camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
         mDevice(device),
-        mCallback(callback) {
+        mResultBatcher(callback) {
+
+    mDeviceInfo = deviceInfo;
+    uint32_t numPartialResults = 1;
+    camera_metadata_entry partialResultsCount =
+            mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
+    if (partialResultsCount.count > 0) {
+        numPartialResults = partialResultsCount.data.i32[0];
+    }
+    mResultBatcher.setNumPartialResults(numPartialResults);
+
     mInitFail = initialize();
 }
 
@@ -177,6 +191,354 @@
     }
 }
 
+CameraDeviceSession::ResultBatcher::ResultBatcher(
+        const sp<ICameraDeviceCallback>& callback) : mCallback(callback) {};
+
+bool CameraDeviceSession::ResultBatcher::InflightBatch::allDelivered() const {
+    if (!mShutterDelivered) return false;
+
+    if (mPartialResultProgress < mNumPartialResults) {
+        return false;
+    }
+
+    for (const auto& pair : mBatchBufs) {
+        if (!pair.second.mDelivered) {
+            return false;
+        }
+    }
+    return true;
+}
+
+void CameraDeviceSession::ResultBatcher::setNumPartialResults(uint32_t n) {
+    Mutex::Autolock _l(mLock);
+    mNumPartialResults = n;
+}
+
+void CameraDeviceSession::ResultBatcher::setBatchedStreams(
+        const std::vector<int>& streamsToBatch) {
+    Mutex::Autolock _l(mLock);
+    mStreamsToBatch = streamsToBatch;
+}
+
+void CameraDeviceSession::ResultBatcher::registerBatch(
+        const hidl_vec<CaptureRequest>& requests) {
+    auto batch = std::make_shared<InflightBatch>();
+    batch->mFirstFrame = requests[0].frameNumber;
+    batch->mBatchSize = requests.size();
+    batch->mLastFrame = batch->mFirstFrame + batch->mBatchSize - 1;
+    batch->mNumPartialResults = mNumPartialResults;
+    for (int id : mStreamsToBatch) {
+        batch->mBatchBufs[id] = InflightBatch::BufferBatch();
+    }
+    Mutex::Autolock _l(mLock);
+    mInflightBatches.push_back(batch);
+}
+
+std::pair<int, std::shared_ptr<CameraDeviceSession::ResultBatcher::InflightBatch>>
+CameraDeviceSession::ResultBatcher::getBatch(
+        uint32_t frameNumber) {
+    Mutex::Autolock _l(mLock);
+    int numBatches = mInflightBatches.size();
+    if (numBatches == 0) {
+        return std::make_pair(NOT_BATCHED, nullptr);
+    }
+    uint32_t frameMin = mInflightBatches[0]->mFirstFrame;
+    uint32_t frameMax = mInflightBatches[numBatches - 1]->mLastFrame;
+    if (frameNumber < frameMin || frameNumber > frameMax) {
+        return std::make_pair(NOT_BATCHED, nullptr);
+    }
+    for (int i = 0; i < numBatches; i++) {
+        if (frameNumber >= mInflightBatches[i]->mFirstFrame &&
+                frameNumber <= mInflightBatches[i]->mLastFrame) {
+            return std::make_pair(i, mInflightBatches[i]);
+        }
+    }
+    return std::make_pair(NOT_BATCHED, nullptr);
+}
+
+void CameraDeviceSession::ResultBatcher::checkAndRemoveFirstBatch() {
+    Mutex::Autolock _l(mLock);
+    if (mInflightBatches.size() > 0) {
+        std::shared_ptr<InflightBatch> batch = mInflightBatches[0];
+        bool shouldRemove = false;
+        {
+            Mutex::Autolock _l(batch->mLock);
+            if (batch->allDelivered()) {
+                batch->mRemoved = true;
+                shouldRemove = true;
+            }
+        }
+        if (shouldRemove) {
+            mInflightBatches.pop_front();
+        }
+    }
+}
+
+void CameraDeviceSession::ResultBatcher::sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch) {
+    if (batch->mShutterDelivered) {
+        ALOGW("%s: batch shutter callback already sent!", __FUNCTION__);
+        return;
+    }
+
+    mCallback->notify(batch->mShutterMsgs);
+    batch->mShutterDelivered = true;
+    batch->mShutterMsgs.clear();
+}
+
+void CameraDeviceSession::ResultBatcher::freeReleaseFences(hidl_vec<CaptureResult>& results) {
+    for (auto& result : results) {
+        if (result.inputBuffer.releaseFence.getNativeHandle() != nullptr) {
+            native_handle_t* handle = const_cast<native_handle_t*>(
+                    result.inputBuffer.releaseFence.getNativeHandle());
+            native_handle_delete(handle);
+        }
+        for (auto& buf : result.outputBuffers) {
+            if (buf.releaseFence.getNativeHandle() != nullptr) {
+                native_handle_t* handle = const_cast<native_handle_t*>(
+                        buf.releaseFence.getNativeHandle());
+                native_handle_delete(handle);
+            }
+        }
+    }
+    return;
+}
+
+void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch) {
+    sendBatchBuffersLocked(batch, mStreamsToBatch);
+}
+
+void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
+        std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams) {
+    size_t batchSize = 0;
+    for (int streamId : streams) {
+        auto it = batch->mBatchBufs.find(streamId);
+        if (it != batch->mBatchBufs.end()) {
+            InflightBatch::BufferBatch& bb = it->second;
+            if (bb.mDelivered) {
+                continue;
+            }
+            if (bb.mBuffers.size() > batchSize) {
+                batchSize = bb.mBuffers.size();
+            }
+        } else {
+            ALOGE("%s: stream ID %d is not batched!", __FUNCTION__, streamId);
+            return;
+        }
+    }
+
+    if (batchSize == 0) {
+        ALOGW("%s: there is no buffer to be delivered for this batch.", __FUNCTION__);
+        for (int streamId : streams) {
+            InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
+            bb.mDelivered = true;
+        }
+        return;
+    }
+
+    hidl_vec<CaptureResult> results;
+    results.resize(batchSize);
+    for (size_t i = 0; i < batchSize; i++) {
+        results[i].frameNumber = batch->mFirstFrame + i;
+        results[i].partialResult = 0; // 0 for buffer only results
+        results[i].inputBuffer.streamId = -1;
+        results[i].inputBuffer.bufferId = 0;
+        results[i].inputBuffer.buffer = nullptr;
+        std::vector<StreamBuffer> outBufs;
+        for (int streamId : streams) {
+            InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
+            if (bb.mDelivered) {
+                continue;
+            }
+            if (i < bb.mBuffers.size()) {
+                outBufs.push_back(bb.mBuffers[i]);
+            }
+        }
+        results[i].outputBuffers = outBufs;
+    }
+    mCallback->processCaptureResult(results);
+    freeReleaseFences(results);
+    for (int streamId : streams) {
+        InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
+        bb.mDelivered = true;
+        bb.mBuffers.clear();
+    }
+}
+
+void CameraDeviceSession::ResultBatcher::sendBatchMetadataLocked(
+    std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx) {
+    if (lastPartialResultIdx <= batch->mPartialResultProgress) {
+        // Result has been delivered. Return
+        ALOGW("%s: partial result %u has been delivered", __FUNCTION__, lastPartialResultIdx);
+        return;
+    }
+
+    std::vector<CaptureResult> results;
+    std::vector<uint32_t> toBeRemovedIdxes;
+    for (auto& pair : batch->mResultMds) {
+        uint32_t partialIdx = pair.first;
+        if (partialIdx > lastPartialResultIdx) {
+            continue;
+        }
+        toBeRemovedIdxes.push_back(partialIdx);
+        InflightBatch::MetadataBatch& mb = pair.second;
+        for (const auto& p : mb.mMds) {
+            CaptureResult result;
+            result.frameNumber = p.first;
+            result.result = std::move(p.second);
+            result.inputBuffer.streamId = -1;
+            result.inputBuffer.bufferId = 0;
+            result.inputBuffer.buffer = nullptr;
+            result.partialResult = partialIdx;
+            results.push_back(std::move(result));
+        }
+        mb.mMds.clear();
+    }
+    mCallback->processCaptureResult(results);
+    batch->mPartialResultProgress = lastPartialResultIdx;
+    for (uint32_t partialIdx : toBeRemovedIdxes) {
+        batch->mResultMds.erase(partialIdx);
+    }
+}
+
+void CameraDeviceSession::ResultBatcher::notifySingleMsg(NotifyMsg& msg) {
+    mCallback->notify({msg});
+    return;
+}
+
+void CameraDeviceSession::ResultBatcher::notify(NotifyMsg& msg) {
+    uint32_t frameNumber;
+    if (CC_LIKELY(msg.type == MsgType::SHUTTER)) {
+        frameNumber = msg.msg.shutter.frameNumber;
+    } else {
+        frameNumber = msg.msg.error.frameNumber;
+    }
+
+    auto pair = getBatch(frameNumber);
+    int batchIdx = pair.first;
+    if (batchIdx == NOT_BATCHED) {
+        notifySingleMsg(msg);
+        return;
+    }
+
+    // When error happened, stop batching for all batches earlier
+    if (CC_UNLIKELY(msg.type == MsgType::ERROR)) {
+        Mutex::Autolock _l(mLock);
+        for (int i = 0; i <= batchIdx; i++) {
+            // Send batched data up
+            std::shared_ptr<InflightBatch> batch = mInflightBatches[0];
+            {
+                Mutex::Autolock _l(batch->mLock);
+                sendBatchShutterCbsLocked(batch);
+                sendBatchBuffersLocked(batch);
+                sendBatchMetadataLocked(batch, mNumPartialResults);
+                if (!batch->allDelivered()) {
+                    ALOGE("%s: error: some batch data not sent back to framework!",
+                            __FUNCTION__);
+                }
+                batch->mRemoved = true;
+            }
+            mInflightBatches.pop_front();
+        }
+        // Send the error up
+        notifySingleMsg(msg);
+        return;
+    }
+    // Queue shutter callbacks for future delivery
+    std::shared_ptr<InflightBatch> batch = pair.second;
+    {
+        Mutex::Autolock _l(batch->mLock);
+        // Check if the batch is removed (mostly by notify error) before lock was acquired
+        if (batch->mRemoved) {
+            // Fall back to non-batch path
+            notifySingleMsg(msg);
+            return;
+        }
+
+        batch->mShutterMsgs.push_back(msg);
+        if (frameNumber == batch->mLastFrame) {
+            sendBatchShutterCbsLocked(batch);
+        }
+    } // end of batch lock scope
+
+    // see if the batch is complete
+    if (frameNumber == batch->mLastFrame) {
+        checkAndRemoveFirstBatch();
+    }
+}
+
+void CameraDeviceSession::ResultBatcher::processOneCaptureResult(CaptureResult& result) {
+    hidl_vec<CaptureResult> results = {result};
+    mCallback->processCaptureResult(results);
+    freeReleaseFences(results);
+    return;
+}
+
+void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& result) {
+    auto pair = getBatch(result.frameNumber);
+    int batchIdx = pair.first;
+    if (batchIdx == NOT_BATCHED) {
+        processOneCaptureResult(result);
+        return;
+    }
+    std::shared_ptr<InflightBatch> batch = pair.second;
+    {
+        Mutex::Autolock _l(batch->mLock);
+        // Check if the batch is removed (mostly by notify error) before lock was acquired
+        if (batch->mRemoved) {
+            // Fall back to non-batch path
+            processOneCaptureResult(result);
+            return;
+        }
+
+        // queue metadata
+        if (result.result.size() != 0) {
+            // Save a copy of metadata
+            batch->mResultMds[result.partialResult].mMds.push_back(
+                    std::make_pair(result.frameNumber, result.result));
+        }
+
+        // queue buffer
+        std::vector<int> filledStreams;
+        std::vector<StreamBuffer> nonBatchedBuffers;
+        for (auto& buffer : result.outputBuffers) {
+            auto it = batch->mBatchBufs.find(buffer.streamId);
+            if (it != batch->mBatchBufs.end()) {
+                InflightBatch::BufferBatch& bb = it->second;
+                bb.mBuffers.push_back(buffer);
+                filledStreams.push_back(buffer.streamId);
+            } else {
+                nonBatchedBuffers.push_back(buffer);
+            }
+        }
+
+        // send non-batched buffers up
+        if (nonBatchedBuffers.size() > 0 || result.inputBuffer.streamId != -1) {
+            CaptureResult nonBatchedResult;
+            nonBatchedResult.frameNumber = result.frameNumber;
+            nonBatchedResult.outputBuffers = nonBatchedBuffers;
+            nonBatchedResult.inputBuffer = result.inputBuffer;
+            nonBatchedResult.partialResult = 0; // 0 for buffer only results
+            processOneCaptureResult(nonBatchedResult);
+        }
+
+        if (result.frameNumber == batch->mLastFrame) {
+            // Send data up
+            if (result.partialResult > 0) {
+                sendBatchMetadataLocked(batch, result.partialResult);
+            }
+            // send buffer up
+            if (filledStreams.size() > 0) {
+                sendBatchBuffersLocked(batch, filledStreams);
+            }
+        }
+    } // end of batch lock scope
+
+    // see if the batch is complete
+    if (result.frameNumber == batch->mLastFrame) {
+        checkAndRemoveFirstBatch();
+    }
+}
+
 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
 Return<void> CameraDeviceSession::constructDefaultRequestSettings(
         RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb)  {
@@ -283,6 +645,16 @@
                 ++it;
             }
         }
+
+        // Track video streams
+        mVideoStreamIds.clear();
+        for (const auto& stream : requestedConfiguration.streams) {
+            if (stream.streamType == StreamType::OUTPUT &&
+                    stream.usage & graphics::allocator::V2_0::ConsumerUsage::VIDEO_ENCODER) {
+                mVideoStreamIds.push_back(stream.id);
+            }
+        }
+        mResultBatcher.setBatchedStreams(mVideoStreamIds);
     }
 
     if (ret == -EINVAL) {
@@ -306,7 +678,26 @@
     mCirculatingBuffers.erase(id);
 }
 
-Return<Status> CameraDeviceSession::processCaptureRequest(const CaptureRequest& request)  {
+Return<void> CameraDeviceSession::processCaptureRequest(
+        const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb)  {
+    uint32_t numRequestProcessed = 0;
+    Status s = Status::OK;
+    for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
+        s = processOneCaptureRequest(requests[i]);
+        if (s != Status::OK) {
+            break;
+        }
+    }
+
+    if (s == Status::OK && requests.size() > 1) {
+        mResultBatcher.registerBatch(requests);
+    }
+
+    _hidl_cb(s, numRequestProcessed);
+    return Void();
+}
+
+Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request)  {
     Status status = initStatus();
     if (status != Status::OK) {
         ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
@@ -437,7 +828,7 @@
     bool hasInputBuf = (hal_result->input_buffer != nullptr);
     size_t numOutputBufs = hal_result->num_output_buffers;
     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
-    {
+    if (numBufs > 0) {
         Mutex::Autolock _l(d->mInflightLock);
         if (hasInputBuf) {
             int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
@@ -463,10 +854,7 @@
     }
     // We don't need to validate/import fences here since we will be passing them to camera service
     // within the scope of this function
-
     CaptureResult result;
-    hidl_vec<native_handle_t*> releaseFences;
-    releaseFences.resize(numBufs);
     result.frameNumber = frameNumber;
     result.partialResult = hal_result->partial_result;
     convertToHidl(hal_result->result, &result.result);
@@ -477,11 +865,11 @@
         result.inputBuffer.status = (BufferStatus) hal_result->input_buffer->status;
         // skip acquire fence since it's no use to camera service
         if (hal_result->input_buffer->release_fence != -1) {
-            releaseFences[numOutputBufs] = native_handle_create(/*numFds*/1, /*numInts*/0);
-            releaseFences[numOutputBufs]->data[0] = hal_result->input_buffer->release_fence;
-            result.inputBuffer.releaseFence = releaseFences[numOutputBufs];
+            native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
+            handle->data[0] = hal_result->input_buffer->release_fence;
+            result.inputBuffer.releaseFence = handle;
         } else {
-            releaseFences[numOutputBufs] = nullptr;
+            result.inputBuffer.releaseFence = nullptr;
         }
     } else {
         result.inputBuffer.streamId = -1;
@@ -495,11 +883,11 @@
         result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
         // skip acquire fence since it's of no use to camera service
         if (hal_result->output_buffers[i].release_fence != -1) {
-            releaseFences[i] = native_handle_create(/*numFds*/1, /*numInts*/0);
-            releaseFences[i]->data[0] = hal_result->output_buffers[i].release_fence;
-            result.outputBuffers[i].releaseFence = releaseFences[i];
+            native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
+            handle->data[0] = hal_result->output_buffers[i].release_fence;
+            result.outputBuffers[i].releaseFence = handle;
         } else {
-            releaseFences[i] = nullptr;
+            result.outputBuffers[i].releaseFence = nullptr;
         }
     }
 
@@ -507,21 +895,17 @@
     // Do this before call back to camera service because camera service might jump to
     // configure_streams right after the processCaptureResult call so we need to finish
     // updating inflight queues first
-    {
+    if (numBufs > 0) {
         Mutex::Autolock _l(d->mInflightLock);
         if (hasInputBuf) {
             int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
             auto key = std::make_pair(streamId, frameNumber);
-            // TODO (b/34169301): currently HAL closed the fence
-            //sHandleImporter.closeFence(d->mInflightBuffers[key].acquire_fence);
             d->mInflightBuffers.erase(key);
         }
 
         for (size_t i = 0; i < numOutputBufs; i++) {
             int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
             auto key = std::make_pair(streamId, frameNumber);
-            // TODO (b/34169301): currently HAL closed the fence
-            //sHandleImporter.closeFence(d->mInflightBuffers[key].acquire_fence);
             d->mInflightBuffers.erase(key);
         }
 
@@ -530,12 +914,7 @@
         }
     }
 
-    d->mCallback->processCaptureResult(result);
-
-    for (size_t i = 0; i < releaseFences.size(); i++) {
-        // We don't close the FD here as HAL needs to signal it later.
-        native_handle_delete(releaseFences[i]);
-    }
+    d->mResultBatcher.processCaptureResult(result);
 }
 
 void CameraDeviceSession::sNotify(
@@ -545,15 +924,16 @@
             const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
     NotifyMsg hidlMsg;
     convertToHidl(msg, &hidlMsg);
+
     if (hidlMsg.type == (MsgType) CAMERA3_MSG_ERROR &&
             hidlMsg.msg.error.errorStreamId != -1) {
         if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
             ALOGE("%s: unknown stream ID %d reports an error!",
                     __FUNCTION__, hidlMsg.msg.error.errorStreamId);
+            return;
         }
-        return;
     }
-    d->mCallback->notify(hidlMsg);
+    d->mResultBatcher.notify(hidlMsg);
 }
 
 } // namespace implementation
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 3786e4b..8923c05 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
 #define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
 
+#include <deque>
+#include <map>
 #include <unordered_map>
 #include "hardware/camera_common.h"
 #include "hardware/camera3.h"
@@ -27,6 +29,7 @@
 #include <hidl/MQDescriptor.h>
 #include <include/convert.h>
 #include "HandleImporter.h"
+#include "CameraMetadata.h"
 
 namespace android {
 namespace hardware {
@@ -64,7 +67,9 @@
 
 struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callback_ops  {
 
-    CameraDeviceSession(camera3_device_t*, const sp<ICameraDeviceCallback>&);
+    CameraDeviceSession(camera3_device_t*,
+                        const camera_metadata_t* deviceInfo,
+                        const sp<ICameraDeviceCallback>&);
     ~CameraDeviceSession();
     // Call by CameraDevice to dump active device states
     void dumpState(const native_handle_t* fd);
@@ -75,9 +80,12 @@
     bool isClosed();
 
     // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
-    Return<void> constructDefaultRequestSettings(RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
-    Return<void> configureStreams(const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
-    Return<Status> processCaptureRequest(const CaptureRequest& request) override;
+    Return<void> constructDefaultRequestSettings(
+            RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
+    Return<void> configureStreams(
+            const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
+    Return<void> processCaptureRequest(
+            const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb) override;
     Return<Status> flush() override;
     Return<void> close() override;
 
@@ -94,7 +102,6 @@
     bool mDisconnected = false;
 
     camera3_device_t* mDevice;
-    const sp<ICameraDeviceCallback> mCallback;
     // Stream ID -> Camera3Stream cache
     std::map<int, Camera3Stream> mStreamMap;
 
@@ -114,6 +121,104 @@
     static HandleImporter& sHandleImporter;
 
     bool mInitFail;
+
+    common::V1_0::helper::CameraMetadata mDeviceInfo;
+
+    class ResultBatcher {
+    public:
+        ResultBatcher(const sp<ICameraDeviceCallback>& callback);
+        void setNumPartialResults(uint32_t n);
+        void setBatchedStreams(const std::vector<int>& streamsToBatch);
+
+        void registerBatch(const hidl_vec<CaptureRequest>& requests);
+        void notify(NotifyMsg& msg);
+        void processCaptureResult(CaptureResult& result);
+
+    private:
+        struct InflightBatch {
+            // Protect access to entire struct. Acquire this lock before read/write any data or
+            // calling any methods. processCaptureResult and notify will compete for this lock
+            // HIDL IPCs might be issued while the lock is held
+            Mutex mLock;
+
+            bool allDelivered() const;
+
+            uint32_t mFirstFrame;
+            uint32_t mLastFrame;
+            uint32_t mBatchSize;
+
+            bool mShutterDelivered = false;
+            std::vector<NotifyMsg> mShutterMsgs;
+
+            struct BufferBatch {
+                bool mDelivered = false;
+                // This currently assumes every batched request will output to the batched stream
+                // and since HAL must always send buffers in order, no frameNumber tracking is
+                // needed
+                std::vector<StreamBuffer> mBuffers;
+            };
+            // Stream ID -> VideoBatch
+            std::unordered_map<int, BufferBatch> mBatchBufs;
+
+            struct MetadataBatch {
+                //                   (frameNumber, metadata)
+                std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
+            };
+            // Partial result IDs that has been delivered to framework
+            uint32_t mNumPartialResults;
+            uint32_t mPartialResultProgress = 0;
+            // partialResult -> MetadataBatch
+            std::map<uint32_t, MetadataBatch> mResultMds;
+
+            // Set to true when batch is removed from mInflightBatches
+            // processCaptureResult and notify must check this flag after acquiring mLock to make
+            // sure this batch isn't removed while waiting for mLock
+            bool mRemoved = false;
+        };
+
+        static const int NOT_BATCHED = -1;
+
+        // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
+        // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
+        // It's possible that the InflightBatch is removed from mInflightBatches before the
+        // InflightBatch::mLock is acquired (most likely caused by an error notification), so
+        // caller must check InflightBatch::mRemoved flag after the lock is acquried.
+        // This method will hold ResultBatcher::mLock briefly
+        std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
+
+        // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
+        // This method will hold ResultBatcher::mLock briefly
+        void checkAndRemoveFirstBatch();
+
+        // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
+        // HIDL IPC methods will be called during these methods.
+        void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
+        // send buffers for all batched streams
+        void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
+        // send buffers for specified streams
+        void sendBatchBuffersLocked(
+                std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
+        void sendBatchMetadataLocked(
+                std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
+        // End of sendXXXX methods
+
+        // helper methods
+        void freeReleaseFences(hidl_vec<CaptureResult>&);
+        void notifySingleMsg(NotifyMsg& msg);
+        void processOneCaptureResult(CaptureResult& result);
+
+        // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
+        // processCaptureRequest, processCaptureResult, notify will compete for this lock
+        // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
+        mutable Mutex mLock;
+        std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
+        uint32_t mNumPartialResults;
+        std::vector<int> mStreamsToBatch;
+        const sp<ICameraDeviceCallback> mCallback;
+    } mResultBatcher;
+
+    std::vector<int> mVideoStreamIds;
+
     bool initialize();
 
     Status initStatus() const;
@@ -129,6 +234,7 @@
 
     void cleanupBuffersLocked(int id);
 
+    Status processOneCaptureRequest(const CaptureRequest& request);
     /**
      * Static callback forwarding methods from HAL to instance
      */
diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp
index 3369a3c..1656325 100644
--- a/camera/provider/2.4/Android.bp
+++ b/camera/provider/2.4/Android.bp
@@ -57,6 +57,8 @@
         "android.hardware.camera.common@1.0",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
     export_shared_lib_headers: [
@@ -67,6 +69,8 @@
         "android.hardware.camera.common@1.0",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
 }
diff --git a/camera/provider/2.4/default/service.cpp b/camera/provider/2.4/default/service.cpp
index cf66e04..df2602e 100644
--- a/camera/provider/2.4/default/service.cpp
+++ b/camera/provider/2.4/default/service.cpp
@@ -25,5 +25,5 @@
 int main()
 {
     ALOGI("Camera provider Service is starting.");
-    return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0");
-}
\ No newline at end of file
+    return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0", /*maxThreads*/ 6);
+}
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 598127f..a79c9fa 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -445,13 +445,13 @@
     hidl_vec<hidl_string> getCameraDeviceNames();
 
     struct EmptyDeviceCb : public ICameraDeviceCallback {
-        virtual Return<void> processCaptureResult(const CaptureResult& /*result*/) override {
+        virtual Return<void> processCaptureResult(const hidl_vec<CaptureResult>& /*results*/) override {
             ALOGI("processCaptureResult callback");
             ADD_FAILURE(); // Empty callback should not reach here
             return Void();
         }
 
-        virtual Return<void> notify(const NotifyMsg& /*msg*/) override {
+        virtual Return<void> notify(const hidl_vec<NotifyMsg>& /*msgs*/) override {
             ALOGI("notify callback");
             ADD_FAILURE(); // Empty callback should not reach here
             return Void();
@@ -460,8 +460,8 @@
 
     struct DeviceCb : public ICameraDeviceCallback {
         DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
-        Return<void> processCaptureResult(const CaptureResult& result) override;
-        Return<void> notify(const NotifyMsg& msg) override;
+        Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override;
+        Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override;
 
      private:
         CameraHidlTest *mParent;               // Parent object
@@ -667,12 +667,13 @@
 }
 
 Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
-        const CaptureResult& result) {
+        const hidl_vec<CaptureResult>& results) {
     if (nullptr == mParent) {
         return Void();
     }
 
     std::unique_lock<std::mutex> l(mParent->mLock);
+    const CaptureResult& result = results[0];
 
     if(mParent->mResultFrameNumber != result.frameNumber) {
         ALOGE("%s: Unexpected frame number! Expected: %u received: %u",
@@ -695,7 +696,8 @@
 }
 
 Return<void> CameraHidlTest::DeviceCb::notify(
-        const NotifyMsg& message) {
+        const hidl_vec<NotifyMsg>& messages) {
+    const NotifyMsg& message = messages[0];
 
     if (MsgType::ERROR == message.type) {
         {
@@ -2477,10 +2479,17 @@
                 mResultFrameNumber = frameNumber;
             }
 
-            Return<Status> returnStatus = session->processCaptureRequest(
-                    request);
+            Status status = Status::INTERNAL_ERROR;
+            uint32_t numRequestProcessed = 0;
+            Return<void> returnStatus = session->processCaptureRequest(
+                    {request},
+                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                        status = s;
+                        numRequestProcessed = n;
+                    });
             ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+            ASSERT_EQ(Status::OK, status);
+            ASSERT_EQ(numRequestProcessed, 1u);
 
             {
                 std::unique_lock<std::mutex> l(mLock);
@@ -2503,9 +2512,14 @@
             }
 
             returnStatus = session->processCaptureRequest(
-                    request);
+                    {request},
+                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                        status = s;
+                        numRequestProcessed = n;
+                    });
             ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+            ASSERT_EQ(Status::OK, status);
+            ASSERT_EQ(numRequestProcessed, 1u);
 
             {
                 std::unique_lock<std::mutex> l(mLock);
@@ -2563,12 +2577,19 @@
                     emptyInputBuffer, outputBuffers};
 
             //Settings were not correctly initialized, we should fail here
-            Return<Status> returnStatus = session->processCaptureRequest(
-                    request);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::INTERNAL_ERROR, returnStatus);
+            Status status = Status::OK;
+            uint32_t numRequestProcessed = 0;
+            Return<void> ret = session->processCaptureRequest(
+                    {request},
+                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                        status = s;
+                        numRequestProcessed = n;
+                    });
+            ASSERT_TRUE(ret.isOk());
+            ASSERT_EQ(Status::INTERNAL_ERROR, status);
+            ASSERT_EQ(numRequestProcessed, 0u);
 
-            Return<void> ret = session->close();
+            ret = session->close();
             ASSERT_TRUE(ret.isOk());
         }
     }
@@ -2609,11 +2630,17 @@
                     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);
+            Status status = Status::OK;
+            uint32_t numRequestProcessed = 0;
+            ret = session->processCaptureRequest(
+                    {request},
+                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                        status = s;
+                        numRequestProcessed = n;
+                    });
+            ASSERT_TRUE(ret.isOk());
+            ASSERT_EQ(Status::INTERNAL_ERROR, status);
+            ASSERT_EQ(numRequestProcessed, 0u);
 
             ret = session->close();
             ASSERT_TRUE(ret.isOk());
@@ -2672,12 +2699,20 @@
                 mResultFrameNumber = frameNumber;
             }
 
-            Return<Status> returnStatus = session->processCaptureRequest(
-                    request);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+            Status status = Status::INTERNAL_ERROR;
+            uint32_t numRequestProcessed = 0;
+            ret = session->processCaptureRequest(
+                    {request},
+                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                        status = s;
+                        numRequestProcessed = n;
+                    });
+
+            ASSERT_TRUE(ret.isOk());
+            ASSERT_EQ(Status::OK, status);
+            ASSERT_EQ(numRequestProcessed, 1u);
             //Flush before waiting for request to complete.
-            returnStatus = session->flush();
+            Return<Status> returnStatus = session->flush();
             ASSERT_TRUE(returnStatus.isOk());
             ASSERT_EQ(Status::OK, returnStatus);
 
diff --git a/configstore/1.0/ISurfaceFlingerConfigs.hal b/configstore/1.0/ISurfaceFlingerConfigs.hal
index ce967ee..c7fb78b 100644
--- a/configstore/1.0/ISurfaceFlingerConfigs.hal
+++ b/configstore/1.0/ISurfaceFlingerConfigs.hal
@@ -84,4 +84,24 @@
      * GL composition.
      */
     useHwcForRGBtoYUV() generates(OptionalBool value);
+
+    /*
+     *  Maximum dimension supported by HWC for virtual display.
+     *  Must be equals to min(max_width, max_height).
+     */
+    maxVirtualDisplaySize() generates (OptionalUInt64 value);
+
+    /*
+     * Indicates if Sync framework is available. Sync framework provides fence
+     * mechanism which significantly reduces buffer processing latency.
+     */
+    hasSyncFramework() generates(OptionalBool value);
+
+    /*
+     * Return true if surface flinger should use vr flinger for compatible vr
+     * apps, false otherwise. Devices that will never be running vr apps should
+     * return false to avoid extra resource usage. Daydream ready devices must
+     * return true for full vr support.
+     */
+    useVrFlinger() generates (OptionalBool value);
 };
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.cpp b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
index c4db9fb..fc66c59 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
@@ -59,6 +59,16 @@
     return Void();
 }
 
+Return<void> SurfaceFlingerConfigs::hasSyncFramework(hasSyncFramework_cb _hidl_cb) {
+    bool value = true;
+#ifdef RUNNING_WITHOUT_SYNC_FRAMEWORK
+    value = false;
+#endif
+    _hidl_cb({true, value});
+    LOG(INFO) << "SurfaceFlinger hasSyncFramework: " << value;
+    return Void();
+}
+
 Return<void> SurfaceFlingerConfigs::hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) {
     bool value = false;
 #ifdef HAS_HDR_DISPLAY
@@ -89,6 +99,30 @@
     return Void();
 }
 
+Return<void> SurfaceFlingerConfigs::maxVirtualDisplaySize(maxVirtualDisplaySize_cb _hidl_cb) {
+  uint64_t maxSize = 0;
+#ifdef MAX_VIRTUAL_DISPLAY_DIMENSION
+  maxSize = MAX_VIRTUAL_DISPLAY_DIMENSION;
+  _hidl_cb({true, maxSize});
+  LOG(INFO) << "SurfaceFlinger MaxVirtualDisplaySize: " << maxSize;
+#else
+  _hidl_cb({false, maxSize});
+#endif
+  return Void();
+}
+
+Return<void> SurfaceFlingerConfigs::useVrFlinger(useVrFlinger_cb _hidl_cb) {
+    bool value = false;
+    bool specified = false;
+#ifdef USE_VR_FLINGER
+    value = true;
+    specified = true;
+#endif
+    _hidl_cb({specified, value});
+    LOG(INFO) << "SurfaceFlinger UseVrFlinger: " << (value ? "true" : "false");
+    return Void();
+}
+
 // Methods from ::android::hidl::base::V1_0::IBase follow.
 ISurfaceFlingerConfigs* HIDL_FETCH_ISurfaceFlingerConfigs(const char* /* name */) {
     return new SurfaceFlingerConfigs();
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.h b/configstore/1.0/default/SurfaceFlingerConfigs.h
index ecd488c..b0aaaf8 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.h
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.h
@@ -32,6 +32,9 @@
     Return<void> hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) override;
     Return<void> presentTimeOffsetFromVSyncNs(presentTimeOffsetFromVSyncNs_cb _hidl_cb) override;
     Return<void> useHwcForRGBtoYUV(useHwcForRGBtoYUV_cb _hidl_cb) override;
+    Return<void> maxVirtualDisplaySize(maxVirtualDisplaySize_cb _hidl_cb) override;
+    Return<void> hasSyncFramework(hasSyncFramework_cb _hidl_cb) override;
+    Return<void> useVrFlinger(useVrFlinger_cb _hidl_cb) override;
 
     // Methods from ::android::hidl::base::V1_0::IBase follow.
 
diff --git a/configstore/1.0/default/service.cpp b/configstore/1.0/default/service.cpp
index caec0ba..cb04215 100644
--- a/configstore/1.0/default/service.cpp
+++ b/configstore/1.0/default/service.cpp
@@ -24,10 +24,18 @@
 using android::hardware::registerPassthroughServiceImplementation;
 using android::hardware::joinRpcThreadpool;
 
+using android::status_t;
+using android::OK;
+
 int main() {
     // TODO(b/34857894): tune the max thread count.
     configureRpcThreadpool(10, true);
-    registerPassthroughServiceImplementation<ISurfaceFlingerConfigs>();
+
+    status_t status;
+
+    status = registerPassthroughServiceImplementation<ISurfaceFlingerConfigs>();
+    LOG_ALWAYS_FATAL_IF(status != OK, "Could not register ISurfaceFlingerConfigs");
+
     // other interface registration comes here
     joinRpcThreadpool();
     return 0;
diff --git a/configstore/1.0/default/surfaceflinger.mk b/configstore/1.0/default/surfaceflinger.mk
index c28524b..7837498 100644
--- a/configstore/1.0/default/surfaceflinger.mk
+++ b/configstore/1.0/default/surfaceflinger.mk
@@ -38,3 +38,15 @@
 ifeq ($(TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS),true)
     LOCAL_CFLAGS += -DFORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS
 endif
+
+ifneq ($(MAX_VIRTUAL_DISPLAY_DIMENSION),)
+    LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=$(MAX_VIRTUAL_DISPLAY_DIMENSION)
+endif
+
+ifeq ($(TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK),true)
+    LOCAL_CFLAGS += -DRUNNING_WITHOUT_SYNC_FRAMEWORK
+endif
+
+ifneq ($(USE_VR_FLINGER),)
+    LOCAL_CFLAGS += -DUSE_VR_FLINGER
+endif
diff --git a/drm/1.0/default/service.cpp b/drm/1.0/default/service.cpp
index d2507c4..a112aaf 100644
--- a/drm/1.0/default/service.cpp
+++ b/drm/1.0/default/service.cpp
@@ -31,7 +31,14 @@
 int main() {
     ALOGD("android.hardware.drm@1.0-service starting...");
     configureRpcThreadpool(8, true /* callerWillJoin */);
-    registerPassthroughServiceImplementation<IDrmFactory>("drm");
-    registerPassthroughServiceImplementation<ICryptoFactory>("crypto");
+    android::status_t status =
+        registerPassthroughServiceImplementation<IDrmFactory>("drm");
+    LOG_ALWAYS_FATAL_IF(
+        status != android::OK,
+        "Error while registering drm service: %d", status);
+    status = registerPassthroughServiceImplementation<ICryptoFactory>("crypto");
+    LOG_ALWAYS_FATAL_IF(
+        status != android::OK,
+        "Error while registering crypto service: %d", status);
     joinRpcThreadpool();
 }
diff --git a/gnss/1.0/default/Gnss.cpp b/gnss/1.0/default/Gnss.cpp
index 9493737..afb659c 100644
--- a/gnss/1.0/default/Gnss.cpp
+++ b/gnss/1.0/default/Gnss.cpp
@@ -46,7 +46,11 @@
     .gnss_sv_status_cb = gnssSvStatusCb,
 };
 
-Gnss::Gnss(gps_device_t* gnssDevice) {
+uint32_t Gnss::sCapabilitiesCached = 0;
+uint16_t Gnss::sYearOfHwCached = 0;
+
+Gnss::Gnss(gps_device_t* gnssDevice) :
+        mDeathRecipient(new GnssHidlDeathRecipient(this)) {
     /* Error out if an instance of the interface already exists. */
     LOG_ALWAYS_FATAL_IF(sInterfaceExists);
     sInterfaceExists = true;
@@ -271,6 +275,9 @@
     if (!ret.isOk()) {
         ALOGE("%s: Unable to invoke callback", __func__);
     }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sCapabilitiesCached = capabilities;
 }
 
 void Gnss::acquireWakelockCb() {
@@ -373,6 +380,9 @@
     if (!ret.isOk()) {
             ALOGE("%s: Unable to invoke callback", __func__);
     }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sYearOfHwCached = info->year_of_hw;
 }
 
 
@@ -383,7 +393,30 @@
         return false;
     }
 
+    if (callback == nullptr)  {
+        ALOGE("%s: Null callback ignored", __func__);
+        return false;
+    }
+
+    if (sGnssCbIface != NULL) {
+        ALOGW("%s called more than once. Unexpected unless test.", __func__);
+        sGnssCbIface->unlinkToDeath(mDeathRecipient);
+    }
+
     sGnssCbIface = callback;
+    callback->linkToDeath(mDeathRecipient, 0 /*cookie*/);
+
+    // If this was received in the past, send it up again to refresh caller.
+    // mGnssIface will override after init() is called below, if needed
+    // (though it's unlikely the gps.h capabilities or system info will change.)
+    if (sCapabilitiesCached != 0) {
+        setCapabilitiesCb(sCapabilitiesCached);
+    }
+    if (sYearOfHwCached != 0) {
+        LegacyGnssSystemInfo info;
+        info.year_of_hw = sYearOfHwCached;
+        setSystemInfoCb(&info);
+    }
 
     return (mGnssIface->init(&sGnssCb) == 0);
 }
@@ -676,6 +709,30 @@
     return mGnssBatching;
 }
 
+void Gnss::handleHidlDeath() {
+    ALOGW("GNSS service noticed HIDL death. Stopping all GNSS operations.");
+
+    // commands down to the HAL implementation
+    stop(); // stop ongoing GPS tracking
+    if (mGnssMeasurement != nullptr) {
+        mGnssMeasurement->close();
+    }
+    if (mGnssNavigationMessage != nullptr) {
+        mGnssNavigationMessage->close();
+    }
+    if (mGnssBatching != nullptr) {
+        mGnssBatching->stop();
+        mGnssBatching->cleanup();
+    }
+    cleanup();
+
+    /*
+     * This has died, so close it off in case (race condition) callbacks happen
+     * before HAL processes above messages.
+     */
+    sGnssCbIface = nullptr;
+}
+
 IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {
     hw_module_t* module;
     IGnss* iface = nullptr;
diff --git a/gnss/1.0/default/Gnss.h b/gnss/1.0/default/Gnss.h
index 63614fa..faf903c 100644
--- a/gnss/1.0/default/Gnss.h
+++ b/gnss/1.0/default/Gnss.h
@@ -52,7 +52,8 @@
  * Represents the standard GNSS interface. Also contains wrapper methods to allow methods from
  * IGnssCallback interface to be passed into the conventional implementation of the GNSS HAL.
  */
-struct Gnss : public IGnss {
+class Gnss : public IGnss {
+  public:
     Gnss(gps_device_t* gnss_device);
     ~Gnss();
 
@@ -122,6 +123,22 @@
     static GpsCallbacks sGnssCb;
 
  private:
+    /*
+     * For handling system-server death while GNSS service lives on.
+     */
+    class GnssHidlDeathRecipient : public hidl_death_recipient {
+      public:
+        GnssHidlDeathRecipient(const sp<Gnss> gnss) : mGnss(gnss) {
+        }
+
+        virtual void serviceDied(uint64_t /*cookie*/,
+                const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+            mGnss->handleHidlDeath();
+        }
+      private:
+        sp<Gnss> mGnss;
+    };
+
     // for wakelock consolidation, see above
     static void acquireWakelockGnss();
     static void releaseWakelockGnss();
@@ -129,6 +146,11 @@
     static bool sWakelockHeldGnss;
     static bool sWakelockHeldFused;
 
+    /*
+     * Cleanup for death notification
+     */
+    void handleHidlDeath();
+
     sp<GnssXtra> mGnssXtraIface = nullptr;
     sp<AGnssRil> mGnssRil = nullptr;
     sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
@@ -139,10 +161,17 @@
     sp<GnssDebug> mGnssDebug = nullptr;
     sp<GnssConfiguration> mGnssConfig = nullptr;
     sp<GnssBatching> mGnssBatching = nullptr;
+
+    sp<GnssHidlDeathRecipient> mDeathRecipient;
+
     const GpsInterface* mGnssIface = nullptr;
     static sp<IGnssCallback> sGnssCbIface;
     static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
     static bool sInterfaceExists;
+
+    // Values saved for resend
+    static uint32_t sCapabilitiesCached;
+    static uint16_t sYearOfHwCached;
 };
 
 extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
diff --git a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
index 8f131cf..21b7136 100644
--- a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
+++ b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
@@ -33,17 +33,16 @@
 using android::hardware::gnss::V1_0::IGnssCallback;
 using android::sp;
 
-#define TIMEOUT_SECONDS 5  // for basic commands/responses
+#define TIMEOUT_SEC 3  // for basic commands/responses
 
 // The main test class for GNSS HAL.
 class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
  public:
   virtual void SetUp() override {
-    /* TODO(b/35678469): Setup the init.rc for VTS such that there's a
-     * single caller
-     * to the GNSS HAL - as part of confirming that the info & capabilities
-     * callbacks trigger.
-     */
+    // Clean between tests
+    capabilities_called_count_ = 0;
+    location_called_count_ = 0;
+    info_called_count_ = 0;
 
     gnss_hal_ = ::testing::VtsHalHidlTargetTestBase::getService<IGnss>();
     ASSERT_NE(gnss_hal_, nullptr);
@@ -53,15 +52,35 @@
 
     auto result = gnss_hal_->setCallback(gnss_cb_);
     if (!result.isOk()) {
-      ALOGE("result of failed callback set %s", result.description().c_str());
+      ALOGE("result of failed setCallback %s", result.description().c_str());
     }
 
     ASSERT_TRUE(result.isOk());
     ASSERT_TRUE(result);
 
-    /* TODO(b/35678469): Implement the capabilities & info (year) checks &
-     * value store here.
+    /*
+     * At least one callback should trigger - it may be capabilites, or
+     * system info first, so wait again if capabilities not received.
      */
+    EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
+    if (capabilities_called_count_ == 0) {
+      EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
+    }
+
+    /*
+     * Generally should be 1 capabilites callback -
+     * or possibly 2 in some recovery cases (default cached & refreshed)
+     */
+    EXPECT_GE(capabilities_called_count_, 1);
+    EXPECT_LE(capabilities_called_count_, 2);
+
+    /*
+     * Clear notify/waiting counter, allowing up till the timeout after
+     * the last reply for final startup messages to arrive (esp. system
+     * info.)
+     */
+    while (wait(TIMEOUT_SEC) == std::cv_status::no_timeout) {
+    }
   }
 
   virtual void TearDown() override {
@@ -93,9 +112,9 @@
 
   /* Callback class for data & Event. */
   class GnssCallback : public IGnssCallback {
+   public:
     GnssHalTest& parent_;
 
-   public:
     GnssCallback(GnssHalTest& parent) : parent_(parent){};
 
     virtual ~GnssCallback() = default;
@@ -171,16 +190,33 @@
  * Sets up the callback, awaits the capabilities, and calls cleanup
  *
  * Since this is just the basic operation of SetUp() and TearDown(),
- * the function definition is intentionally kept empty
+ * the function definition is intentionally empty
  */
 TEST_F(GnssHalTest, SetCallbackCapabilitiesCleanup) {}
 
-void CheckLocation(GnssLocation& location) {
+/*
+ * CheckLocation:
+ * Helper function to vet Location fields
+ */
+
+void CheckLocation(GnssLocation& location, bool checkAccuracies) {
   EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
   EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
   EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
   EXPECT_TRUE(location.gnssLocationFlags &
               GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
+  // New uncertainties available in O must be provided,
+  // at least when paired with modern hardware (2017+)
+  if (checkAccuracies) {
+    EXPECT_TRUE(location.gnssLocationFlags &
+                GnssLocationFlags::HAS_VERTICAL_ACCURACY);
+    EXPECT_TRUE(location.gnssLocationFlags &
+                GnssLocationFlags::HAS_SPEED_ACCURACY);
+    if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+      EXPECT_TRUE(location.gnssLocationFlags &
+                  GnssLocationFlags::HAS_BEARING_ACCURACY);
+    }
+  }
   EXPECT_GE(location.latitudeDegrees, -90.0);
   EXPECT_LE(location.latitudeDegrees, 90.0);
   EXPECT_GE(location.longitudeDegrees, -180.0);
@@ -190,12 +226,17 @@
   EXPECT_GE(location.speedMetersPerSec, 0.0);
   EXPECT_LE(location.speedMetersPerSec, 5.0);  // VTS tests are stationary.
 
+  // Non-zero speeds must be reported with an associated bearing
+  if (location.speedMetersPerSec > 0.0) {
+    EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
+  }
+
   /*
    * Tolerating some especially high values for accuracy estimate, in case of
-   * first fix with especially poor geoemtry (happens occasionally)
+   * first fix with especially poor geometry (happens occasionally)
    */
   EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
-  EXPECT_LE(location.horizontalAccuracyMeters, 200.0);
+  EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
 
   /*
    * Some devices may define bearing as -180 to +180, others as 0 to 360.
@@ -220,11 +261,6 @@
 
   // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
   EXPECT_GT(location.timestamp, 1.48e12);
-
-  /* TODO(b/35678469): Check if the hardware year is 2017+, and if so,
-   * that bearing, plus vertical, speed & bearing accuracy are present.
-   * And allow bearing to be not present, only if associated with a speed of 0.0
-   */
 }
 
 /*
@@ -241,6 +277,9 @@
 #define LOCATION_TIMEOUT_SUBSEQUENT_SEC 3
 #define LOCATIONS_TO_CHECK 5
 
+  bool checkMoreAccuracies =
+      (info_called_count_ > 0 && last_info_.yearOfHw >= 2017);
+
   auto result = gnss_hal_->setPositionMode(
       IGnss::GnssPositionMode::MS_BASED,
       IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC, MIN_INTERVAL_MSEC,
@@ -254,15 +293,18 @@
   ASSERT_TRUE(result.isOk());
   ASSERT_TRUE(result);
 
-  EXPECT_EQ(std::cv_status::no_timeout, wait(LOCATION_TIMEOUT_FIRST_SEC));
-  EXPECT_EQ(location_called_count_, 1);
-  CheckLocation(last_location_);
+  // GPS signals initially optional for this test, so don't expect no timeout
+  // yet
+  wait(LOCATION_TIMEOUT_FIRST_SEC);
+  if (location_called_count_ > 0) {
+    CheckLocation(last_location_, checkMoreAccuracies);
+  }
 
   for (int i = 1; i < LOCATIONS_TO_CHECK; i++) {
-    EXPECT_EQ(std::cv_status::no_timeout,
-              wait(LOCATION_TIMEOUT_SUBSEQUENT_SEC));
-    EXPECT_EQ(location_called_count_, i + 1);
-    CheckLocation(last_location_);
+    wait(LOCATION_TIMEOUT_SUBSEQUENT_SEC);
+    if (location_called_count_ > 0) {
+      CheckLocation(last_location_, checkMoreAccuracies);
+    }
   }
 
   result = gnss_hal_->stop();
@@ -276,4 +318,4 @@
   int status = RUN_ALL_TESTS();
   ALOGI("Test result = %d", status);
   return status;
-}
+}
\ No newline at end of file
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index d5da943..0367fcd 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -37,6 +37,7 @@
         "liblog",
         "libsync",
         "libutils",
+        "libhwc2on1adapter"
     ],
 }
 
diff --git a/graphics/composer/2.1/default/ComposerClient.cpp b/graphics/composer/2.1/default/ComposerClient.cpp
index a2d5d4b..d599b44 100644
--- a/graphics/composer/2.1/default/ComposerClient.cpp
+++ b/graphics/composer/2.1/default/ComposerClient.cpp
@@ -21,7 +21,7 @@
 #include <log/log.h>
 
 #include "ComposerClient.h"
-#include "Hwc.h"
+#include "ComposerBase.h"
 #include "IComposerCommandBuffer.h"
 
 namespace android {
diff --git a/graphics/composer/2.1/default/ComposerClient.h b/graphics/composer/2.1/default/ComposerClient.h
index 14da1f8..c973351 100644
--- a/graphics/composer/2.1/default/ComposerClient.h
+++ b/graphics/composer/2.1/default/ComposerClient.h
@@ -21,8 +21,9 @@
 #include <unordered_map>
 #include <vector>
 
-#include "Hwc.h"
+#include <hardware/hwcomposer2.h>
 #include "IComposerCommandBuffer.h"
+#include "ComposerBase.h"
 
 namespace android {
 namespace hardware {
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index cf82967..1497065 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -16,12 +16,14 @@
 
 #define LOG_TAG "HwcPassthrough"
 
-#include <type_traits>
+#include "Hwc.h"
 
+#include <type_traits>
 #include <log/log.h>
 
 #include "ComposerClient.h"
-#include "Hwc.h"
+#include "hardware/hwcomposer.h"
+#include "hwc2on1adapter/HWC2On1Adapter.h"
 
 namespace android {
 namespace hardware {
@@ -30,13 +32,36 @@
 namespace V2_1 {
 namespace implementation {
 
+
 HwcHal::HwcHal(const hw_module_t* module)
-    : mDevice(nullptr), mDispatch()
+    : mDevice(nullptr), mDispatch(), mAdapter()
 {
-    int status = hwc2_open(module, &mDevice);
-    if (status) {
-        LOG_ALWAYS_FATAL("failed to open hwcomposer2 device: %s",
-                strerror(-status));
+    // Determine what kind of module is available (HWC2 vs HWC1.X).
+    hw_device_t* device = nullptr;
+    int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
+    if (error != 0) {
+        ALOGE("Failed to open HWC device (%s), aborting", strerror(-error));
+        abort();
+    }
+    uint32_t majorVersion = (device->version >> 24) & 0xF;
+
+    // If we don't have a HWC2, we need to wrap whatever we have in an adapter.
+    if (majorVersion != 2) {
+        uint32_t minorVersion = device->version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
+        minorVersion = (minorVersion >> 16) & 0xF;
+        ALOGI("Found HWC implementation v%d.%d", majorVersion, minorVersion);
+        if (minorVersion < 1) {
+            ALOGE("Cannot adapt to HWC version %d.%d. Minimum supported is 1.1",
+                  majorVersion, minorVersion);
+            abort();
+        }
+        mAdapter = std::make_unique<HWC2On1Adapter>(
+                reinterpret_cast<hwc_composer_device_1*>(device));
+
+        // Place the adapter in front of the device module.
+        mDevice = mAdapter.get();
+    } else {
+        mDevice = reinterpret_cast<hwc2_device_t*>(device);
     }
 
     initCapabilities();
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
index ca08cf0..b45389a 100644
--- a/graphics/composer/2.1/default/Hwc.h
+++ b/graphics/composer/2.1/default/Hwc.h
@@ -18,15 +18,23 @@
 #define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
 
 #include <mutex>
+#include <memory>
 #include <unordered_set>
 #include <vector>
 
 #include <android/hardware/graphics/composer/2.1/IComposer.h>
+#define HWC2_INCLUDE_STRINGIFICATION
+#define HWC2_USE_CPP11
 #include <hardware/hwcomposer2.h>
-
+#undef HWC2_INCLUDE_STRINGIFICATION
+#undef HWC2_USE_CPP11
 #include "ComposerBase.h"
 
 namespace android {
+    class HWC2On1Adapter;
+}
+
+namespace android {
 namespace hardware {
 namespace graphics {
 namespace composer {
@@ -204,6 +212,10 @@
 
     std::mutex mClientMutex;
     wp<ComposerClient> mClient;
+
+    // If the HWC implementation version is < 2.0, use an adapter to interface
+    // between HWC 2.0 <-> HWC 1.X.
+    std::unique_ptr<HWC2On1Adapter> mAdapter;
 };
 
 extern "C" IComposer* HIDL_FETCH_IComposer(const char* name);
diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal
index bf50792..d21bf0b 100644
--- a/radio/1.0/IRadioResponse.hal
+++ b/radio/1.0/IRadioResponse.hal
@@ -280,13 +280,34 @@
 
     /*
      * @param info Response info struct containing response type, serial no. and error
-     * @param failCauseInfo Contains LastCallFailCause and vendor cause code. GSM failure reasons
-     *        are mapped to cause codes defined in TS 24.008 Annex H where possible. CDMA
-     *        failure reasons are derived from the possible call failure scenarios
-     *        described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard.
+     * @param failCauseInfo Contains LastCallFailCause and vendor cause code.
      *
-     * The implementation must return LastCallFailCause:ERROR_UNSPECIFIED for blocked
-     * MO calls by restricted state (See unsolRestrictedStateChanged)
+     *   The vendor cause code must be used for debugging purpose only.
+     *   The implementation must return one of the values of LastCallFailCause
+     *   as mentioned below
+     *
+     *   GSM failure reasons codes for the cause codes defined in TS 24.008 Annex H
+     *   where possible.
+     *   CDMA failure reasons codes for the possible call failure scenarios
+     *   described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard.
+     *   Any of the following reason codes if the call is failed or dropped due to reason
+     *   mentioned with in the braces.
+     *      LastCallFailCause:RADIO_OFF (Radio is OFF)
+     *      LastCallFailCause:OUT_OF_SERVICE (No cell coverage)
+     *      LastCallFailCause:NO_VALID_SIM (No valid SIM)
+     *      LastCallFailCause:RADIO_INTERNAL_ERROR (Modem hit unexpected error scenario)
+     *      LastCallFailCause:NETWORK_RESP_TIMEOUT (No response from network)
+     *      LastCallFailCause:NETWORK_REJECT (Explicit network reject)
+     *      LastCallFailCause:RADIO_ACCESS_FAILURE (RRC connection failure. Eg.RACH)
+     *      LastCallFailCause:RADIO_LINK_FAILURE (Radio Link Failure)
+     *      LastCallFailCause:RADIO_LINK_LOST (Radio link lost due to poor coverage)
+     *      LastCallFailCause:RADIO_UPLINK_FAILURE (Radio uplink failure)
+     *      LastCallFailCause:RADIO_SETUP_FAILURE (RRC connection setup failure)
+     *      LastCallFailCause:RADIO_RELEASE_NORMAL (RRC connection release, normal)
+     *      LastCallFailCause:RADIO_RELEASE_ABNORMAL (RRC connection release, abnormal)
+     *      LastCallFailCause:ACCESS_CLASS_BLOCKED (Access class barring)
+     *      LastCallFailCause:NETWORK_DETACH (Explicit network detach)
+     *   OEM causes (LastCallFailCause:OEM_CAUSE_XX) must be used for debug purpose only
      *
      * If the implementation does not have access to the exact cause codes,
      * then it must return one of the values listed in LastCallFailCause,
diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal
index 9b904a5..ad9f392 100644
--- a/radio/1.0/types.hal
+++ b/radio/1.0/types.hal
@@ -383,6 +383,21 @@
     DIAL_MODIFIED_TO_USSD = 244,          // STK Call Control
     DIAL_MODIFIED_TO_SS = 245,
     DIAL_MODIFIED_TO_DIAL = 246,
+    RADIO_OFF = 247,                      // Radio is OFF
+    OUT_OF_SERVICE = 248,                 // No cellular coverage
+    NO_VALID_SIM = 249,                   // No valid SIM is present
+    RADIO_INTERNAL_ERROR = 250,           // Internal error at Modem
+    NETWORK_RESP_TIMEOUT = 251,           // No response from network
+    NETWORK_REJECT = 252,                 // Explicit network reject
+    RADIO_ACCESS_FAILURE = 253,           // RRC connection failure. Eg.RACH
+    RADIO_LINK_FAILURE = 254,             // Radio Link Failure
+    RADIO_LINK_LOST = 255,                // Radio link lost due to poor coverage
+    RADIO_UPLINK_FAILURE = 256,           // Radio uplink failure
+    RADIO_SETUP_FAILURE = 257,            // RRC connection setup failure
+    RADIO_RELEASE_NORMAL = 258,           // RRC connection release, normal
+    RADIO_RELEASE_ABNORMAL = 259,         // RRC connection release, abnormal
+    ACCESS_CLASS_BLOCKED = 260,           // Access class barring
+    NETWORK_DETACH = 261,                 // Explicit network detach
     CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000,
     CDMA_DROP = 1001,
     CDMA_INTERCEPT = 1002,
@@ -393,10 +408,29 @@
     CDMA_PREEMPTED = 1007,
     CDMA_NOT_EMERGENCY = 1008,            // For non-emergency number dialed during emergency
                                           // callback mode
-    CDMA_ACCESS_BLOCKED = 1009,           // This error will be deprecated soon,
+    CDMA_ACCESS_BLOCKED = 1009,
+
+    /* OEM specific error codes. Used to distinguish error from
+     * CALL_FAIL_ERROR_UNSPECIFIED and help assist debugging */
+    OEM_CAUSE_1 = 0xf001,
+    OEM_CAUSE_2 = 0xf002,
+    OEM_CAUSE_3 = 0xf003,
+    OEM_CAUSE_4 = 0xf004,
+    OEM_CAUSE_5 = 0xf005,
+    OEM_CAUSE_6 = 0xf006,
+    OEM_CAUSE_7 = 0xf007,
+    OEM_CAUSE_8 = 0xf008,
+    OEM_CAUSE_9 = 0xf009,
+    OEM_CAUSE_10 = 0xf00a,
+    OEM_CAUSE_11 = 0xf00b,
+    OEM_CAUSE_12 = 0xf00c,
+    OEM_CAUSE_13 = 0xf00d,
+    OEM_CAUSE_14 = 0xf00e,
+    OEM_CAUSE_15 = 0xf00f,
+
+    ERROR_UNSPECIFIED = 0xffff,           // This error will be deprecated soon,
                                           // vendor code must make sure to map error
                                           // code to specific error
-    ERROR_UNSPECIFIED = 0xffff,
 };
 
 enum DataCallFailCause : int32_t {
diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp
index 7f16163..24e3926 100644
--- a/radio/1.0/vts/functional/Android.bp
+++ b/radio/1.0/vts/functional/Android.bp
@@ -17,11 +17,16 @@
 cc_test {
     name: "VtsHalRadioV1_0TargetTest",
     defaults: ["hidl_defaults"],
-    srcs: ["radio_hidl_hal_test.cpp",
-           "radio_response.cpp",
-           "radio_hidl_hal_voice.cpp",
+    srcs: ["radio_hidl_hal_cell_broadcast.cpp",
+           "radio_hidl_hal_data.cpp",
            "radio_hidl_hal_icc.cpp",
+           "radio_hidl_hal_ims.cpp",
+           "radio_hidl_hal_misc.cpp",
            "radio_hidl_hal_sms.cpp",
+           "radio_hidl_hal_stk.cpp",
+           "radio_hidl_hal_test.cpp",
+           "radio_hidl_hal_voice.cpp",
+           "radio_response.cpp",
            "VtsHalRadioV1_0TargetTest.cpp"],
     shared_libs: [
         "libbase",
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp b/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
new file mode 100644
index 0000000..d87ce5f
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
@@ -0,0 +1,174 @@
+/*
+ * 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<radio_hidl_hal_utils.h>
+
+using namespace ::android::hardware::radio::V1_0;
+
+/*
+ * Test IRadio.setGsmBroadcastConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, setGsmBroadcastConfig) {
+    int serial = 0;
+
+    // Create GsmBroadcastSmsConfigInfo #1
+    GsmBroadcastSmsConfigInfo gbSmsConfig1;
+    gbSmsConfig1.fromServiceId = 4352;
+    gbSmsConfig1.toServiceId = 4354;
+    gbSmsConfig1.fromCodeScheme = 0;
+    gbSmsConfig1.toCodeScheme = 255;
+    gbSmsConfig1.selected = true;
+
+    // Create GsmBroadcastSmsConfigInfo #2
+    GsmBroadcastSmsConfigInfo gbSmsConfig2;
+    gbSmsConfig2.fromServiceId = 4356;
+    gbSmsConfig2.toServiceId = 4356;
+    gbSmsConfig2.fromCodeScheme = 0;
+    gbSmsConfig2.toCodeScheme = 255;
+    gbSmsConfig2.selected = true;
+
+    // Create GsmBroadcastSmsConfigInfo #3
+    GsmBroadcastSmsConfigInfo gbSmsConfig3;
+    gbSmsConfig3.fromServiceId = 4370;
+    gbSmsConfig3.toServiceId = 4379;
+    gbSmsConfig3.fromCodeScheme = 0;
+    gbSmsConfig3.toCodeScheme = 255;
+    gbSmsConfig3.selected = true;
+
+    // Create GsmBroadcastSmsConfigInfo #4
+    GsmBroadcastSmsConfigInfo gbSmsConfig4;
+    gbSmsConfig4.fromServiceId = 4383;
+    gbSmsConfig4.toServiceId = 4391;
+    gbSmsConfig4.fromCodeScheme = 0;
+    gbSmsConfig4.toCodeScheme = 255;
+    gbSmsConfig4.selected = true;
+
+    // Create GsmBroadcastSmsConfigInfo #5
+    GsmBroadcastSmsConfigInfo gbSmsConfig5;
+    gbSmsConfig5.fromServiceId = 4392;
+    gbSmsConfig5.toServiceId = 4392;
+    gbSmsConfig5.fromCodeScheme = 0;
+    gbSmsConfig5.toCodeScheme = 255;
+    gbSmsConfig5.selected = true;
+
+    android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo> gsmBroadcastSmsConfigsInfoList
+        = {gbSmsConfig1, gbSmsConfig2, gbSmsConfig3, gbSmsConfig4, gbSmsConfig5};
+
+    radio->setGsmBroadcastConfig(++serial, gsmBroadcastSmsConfigsInfoList);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.getGsmBroadcastConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, getGsmBroadcastConfig) {
+    int serial = 0;
+
+    radio->getGsmBroadcastConfig(++serial);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.setCdmaBroadcastConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, setCdmaBroadcastConfig) {
+    int serial = 0;
+
+    CdmaBroadcastSmsConfigInfo cbSmsConfig;
+    cbSmsConfig.serviceCategory = 4096;
+    cbSmsConfig.language = 1;
+    cbSmsConfig.selected = true;
+
+    android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo> cdmaBroadcastSmsConfigInfoList
+        = {cbSmsConfig};
+
+    radio->setCdmaBroadcastConfig(++serial, cdmaBroadcastSmsConfigInfoList);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.getCdmaBroadcastConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCdmaBroadcastConfig) {
+    int serial = 0;
+
+    radio->getCdmaBroadcastConfig(++serial);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.setCdmaBroadcastActivation() for the response returned.
+ */
+TEST_F(RadioHidlTest, setCdmaBroadcastActivation) {
+    int serial = 0;
+    bool activate = false;
+
+    radio->setCdmaBroadcastActivation(++serial, activate);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.setGsmBroadcastActivation() for the response returned.
+ */
+TEST_F(RadioHidlTest, setGsmBroadcastActivation) {
+    int serial = 0;
+    bool activate = false;
+
+    radio->setGsmBroadcastActivation(++serial, activate);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
new file mode 100644
index 0000000..06cab6a
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -0,0 +1,219 @@
+/*
+ * 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<radio_hidl_hal_utils.h>
+
+using namespace ::android::hardware::radio::V1_0;
+
+/*
+ * Test IRadio.getDataRegistrationState() for the response returned.
+ */
+TEST_F(RadioHidlTest, getDataRegistrationState) {
+    int serial = 0;
+
+    radio->getDataRegistrationState(++serial);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.setupDataCall() for the response returned.
+ */
+TEST_F(RadioHidlTest, setupDataCall) {
+    int serial = 0;
+
+    RadioTechnology radioTechnology = RadioTechnology::LTE;
+
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileId::IMS;
+    dataProfileInfo.apn = hidl_string("VZWIMS");
+    dataProfileInfo.protocol = hidl_string("IPV4V6");
+    dataProfileInfo.roamingProtocol = hidl_string("IPV6");
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = "";
+    dataProfileInfo.password = "";
+    dataProfileInfo.type = DataProfileInfoType::THREE_GPP2;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap = 320;
+    dataProfileInfo.bearerBitmap = 161543;
+    dataProfileInfo.mtu = 0;
+    dataProfileInfo.mvnoType = MvnoType::NONE;
+    dataProfileInfo.mvnoMatchData = hidl_string();
+
+    bool modemCognitive = false;
+    bool roamingAllowed = false;
+    bool isRoaming = false;
+
+    radio->setupDataCall(++serial, radioTechnology, dataProfileInfo, modemCognitive,
+           roamingAllowed, isRoaming);
+
+    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_FALSE(RadioError::NONE == radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.deactivateDataCall() for the response returned.
+ */
+TEST_F(RadioHidlTest, deactivateDataCall) {
+    int serial = 0;
+    int cid = 1;
+    bool reasonRadioShutDown = false;
+
+    radio->deactivateDataCall(++serial, cid, reasonRadioShutDown);
+
+    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) {
+        EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.getDataCallList() for the response returned.
+ */
+TEST_F(RadioHidlTest, getDataCallList) {
+    int serial = 0;
+
+    radio->getDataCallList(++serial);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.setInitialAttachApn() for the response returned.
+ */
+TEST_F(RadioHidlTest, setInitialAttachApn) {
+    int serial = 0;
+
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileId::IMS;
+    dataProfileInfo.apn = hidl_string("VZWIMS");
+    dataProfileInfo.protocol = hidl_string("IPV4V6");
+    dataProfileInfo.roamingProtocol = hidl_string("IPV6");
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = "";
+    dataProfileInfo.password = "";
+    dataProfileInfo.type = DataProfileInfoType::THREE_GPP2;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap = 320;
+    dataProfileInfo.bearerBitmap = 161543;
+    dataProfileInfo.mtu = 0;
+    dataProfileInfo.mvnoType = MvnoType::NONE;
+    dataProfileInfo.mvnoMatchData = hidl_string();
+
+    bool modemCognitive = true;
+    bool isRoaming = false;
+
+    radio->setInitialAttachApn(++serial, dataProfileInfo,
+           modemCognitive, isRoaming);
+
+    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_FALSE(RadioError::NONE == radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.setDataAllowed() for the response returned.
+ */
+TEST_F(RadioHidlTest, setDataAllowed) {
+    int serial = 0;
+    bool allow = true;
+
+    radio->setDataAllowed(++serial, allow);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.setDataProfile() for the response returned.
+ */
+TEST_F(RadioHidlTest, setDataProfile) {
+    int serial = 0;
+
+    // Create a dataProfileInfo
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileId::IMS;
+    dataProfileInfo.apn = hidl_string("VZWIMS");
+    dataProfileInfo.protocol = hidl_string("IPV4V6");
+    dataProfileInfo.roamingProtocol = hidl_string("IPV6");
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = "";
+    dataProfileInfo.password = "";
+    dataProfileInfo.type = DataProfileInfoType::THREE_GPP2;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap = 320;
+    dataProfileInfo.bearerBitmap = 161543;
+    dataProfileInfo.mtu = 0;
+    dataProfileInfo.mvnoType = MvnoType::NONE;
+    dataProfileInfo.mvnoMatchData = hidl_string();
+
+    // Create a dataProfileInfoList
+    android::hardware::hidl_vec<DataProfileInfo> dataProfileInfoList = {dataProfileInfo};
+
+    bool isRoadming = false;
+
+    radio->setDataProfile(++serial, dataProfileInfoList, isRoadming);
+
+    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) {
+        // TODO(shuoq): Will add error check when we know the expected error from QC
+    }
+}
+
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
index bd979b0..9cae9c2 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
@@ -287,4 +287,20 @@
         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
         EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
     }
+}
+
+/*
+ * Test IRadio.supplyNetworkDepersonalization() for the response returned.
+ */
+TEST_F(RadioHidlTest, supplyNetworkDepersonalization) {
+    int serial = 1;
+
+    radio->supplyNetworkDepersonalization(serial, hidl_string("test"));
+    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(radioRsp->rspInfo.error == RadioError::PASSWORD_INCORRECT);
+    }
 }
\ No newline at end of file
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
new file mode 100644
index 0000000..fdc39d8
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
@@ -0,0 +1,200 @@
+/*
+ * 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<radio_hidl_hal_utils.h>
+
+using namespace ::android::hardware::radio::V1_0;
+
+/*
+ * Test IRadio.getClir() for the response returned.
+ */
+TEST_F(RadioHidlTest, getClir) {
+    int serial = 0;
+
+    radio->getClir(++serial);
+
+    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(radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+    }
+}
+
+/*
+ * Test IRadio.setClir() for the response returned.
+ */
+TEST_F(RadioHidlTest, setClir) {
+    int serial = 0;
+    int32_t status = 1;
+
+    radio->setClir(++serial, status);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.getFacilityLockForApp() for the response returned.
+ */
+TEST_F(RadioHidlTest, getFacilityLockForApp) {
+    int serial = 0;
+    std::string facility = "";
+    std::string password = "";
+    int32_t serviceClass = 1;
+    std::string appId = "";
+
+    radio->getFacilityLockForApp(++serial, facility, password, serviceClass, appId);
+
+    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(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+    }
+}
+
+/*
+ * Test IRadio.setFacilityLockForApp() for the response returned.
+ */
+TEST_F(RadioHidlTest, setFacilityLockForApp) {
+    int serial = 0;
+    std::string facility = "";
+    bool lockState = false;
+    std::string password = "";
+    int32_t serviceClass = 1;
+    std::string appId = "";
+
+    radio->setFacilityLockForApp(++serial, facility, lockState, password, serviceClass, appId);
+
+    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(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+    }
+}
+
+/*
+ * Test IRadio.setBarringPassword() for the response returned.
+ */
+TEST_F(RadioHidlTest, setBarringPassword) {
+    int serial = 0;
+    std::string facility = "";
+    std::string oldPassword = "";
+    std::string newPassword = "";
+
+    radio->setBarringPassword(++serial, facility, oldPassword, newPassword);
+
+    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(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+    }
+}
+
+/*
+ * Test IRadio.getClip() for the response returned.
+ */
+TEST_F(RadioHidlTest, getClip) {
+    int serial = 0;
+
+    radio->getClip(++serial);
+
+    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(radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+    }
+}
+
+/*
+ * Test IRadio.setSuppServiceNotifications() for the response returned.
+ */
+TEST_F(RadioHidlTest, setSuppServiceNotifications) {
+    int serial = 0;
+    bool enable = false;
+
+    radio->setSuppServiceNotifications(++serial, enable);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.requestIsimAuthentication() for the response returned.
+ */
+TEST_F(RadioHidlTest, requestIsimAuthentication) {
+    int serial = 0;
+    std::string challenge = "";
+
+    radio->requestIsimAuthentication(++serial, challenge);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.getImsRegistrationState() for the response returned.
+ */
+TEST_F(RadioHidlTest, getImsRegistrationState) {
+    int serial = 0;
+
+    radio->getImsRegistrationState(++serial);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
new file mode 100644
index 0000000..5fa11fc
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -0,0 +1,774 @@
+/*
+ * 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<radio_hidl_hal_utils.h>
+
+/*
+ * Test IRadio.getSignalStrength() for the response returned.
+ */
+TEST_F(RadioHidlTest, getSignalStrength) {
+    int serial = 1;
+
+    radio->getSignalStrength(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getVoiceRegistrationState() for the response returned.
+ */
+TEST_F(RadioHidlTest, getVoiceRegistrationState) {
+    int serial = 1;
+
+    radio->getVoiceRegistrationState(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getOperator() for the response returned.
+ */
+TEST_F(RadioHidlTest, getOperator) {
+    int serial = 1;
+
+    radio->getOperator(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setRadioPower() for the response returned.
+ */
+TEST_F(RadioHidlTest, setRadioPower) {
+    int serial = 1;
+
+    radio->setRadioPower(++serial, 0);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getNetworkSelectionMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, getNetworkSelectionMode) {
+    int serial = 1;
+
+    radio->getNetworkSelectionMode(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setNetworkSelectionModeAutomatic() for the response returned.
+ */
+TEST_F(RadioHidlTest, setNetworkSelectionModeAutomatic) {
+    int serial = 1;
+
+    radio->setNetworkSelectionModeAutomatic(++serial);
+    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(radioRsp->rspInfo.error == RadioError::ILLEGAL_SIM_OR_ME);
+    }
+}
+
+/*
+ * Test IRadio.setNetworkSelectionModeManual() for the response returned.
+ */
+TEST_F(RadioHidlTest, setNetworkSelectionModeManual) {
+    int serial = 1;
+
+    radio->setNetworkSelectionModeManual(++serial, "123456");
+    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(radioRsp->rspInfo.error == RadioError::ILLEGAL_SIM_OR_ME);
+    }
+}
+
+/*
+ * Test IRadio.getAvailableNetworks() for the response returned.
+ */
+TEST_F(RadioHidlTest, getAvailableNetworks) {
+    int serial = 1;
+
+    radio->getAvailableNetworks(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getBasebandVersion() for the response returned.
+ */
+TEST_F(RadioHidlTest, getBasebandVersion) {
+    int serial = 1;
+
+    radio->getBasebandVersion(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setBandMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, setBandMode) {
+    int serial = 1;
+
+    radio->setBandMode(++serial, RadioBandMode::BAND_MODE_USA);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getAvailableBandModes() for the response returned.
+ */
+TEST_F(RadioHidlTest, getAvailableBandModes) {
+    int serial = 1;
+
+    radio->getAvailableBandModes(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setPreferredNetworkType() for the response returned.
+ */
+TEST_F(RadioHidlTest, setPreferredNetworkType) {
+    int serial = 1;
+
+    radio->setPreferredNetworkType(++serial, PreferredNetworkType::GSM_ONLY);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getPreferredNetworkType() for the response returned.
+ */
+TEST_F(RadioHidlTest, getPreferredNetworkType) {
+    int serial = 1;
+
+    radio->getPreferredNetworkType(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getNeighboringCids() for the response returned.
+ */
+TEST_F(RadioHidlTest, getNeighboringCids) {
+    int serial = 1;
+
+    radio->getNeighboringCids(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setLocationUpdates() for the response returned.
+ */
+TEST_F(RadioHidlTest, setLocationUpdates) {
+    int serial = 1;
+
+    radio->setLocationUpdates(++serial, true);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setCdmaRoamingPreference() for the response returned.
+ */
+TEST_F(RadioHidlTest, setCdmaRoamingPreference) {
+    int serial = 1;
+
+    radio->setCdmaRoamingPreference(++serial, CdmaRoamingType::HOME_NETWORK);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getCdmaRoamingPreference() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCdmaRoamingPreference) {
+    int serial = 1;
+
+    radio->getCdmaRoamingPreference(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getTTYMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, getTTYMode) {
+    int serial = 1;
+
+    radio->getTTYMode(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setTTYMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, setTTYMode) {
+    int serial = 1;
+
+    radio->setTTYMode(++serial, TtyMode::OFF);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setPreferredVoicePrivacy() for the response returned.
+ */
+TEST_F(RadioHidlTest, setPreferredVoicePrivacy) {
+    int serial = 1;
+
+    radio->setPreferredVoicePrivacy(++serial, true);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getPreferredVoicePrivacy() for the response returned.
+ */
+TEST_F(RadioHidlTest, getPreferredVoicePrivacy) {
+    int serial = 1;
+
+    radio->getPreferredVoicePrivacy(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getCDMASubscription() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCDMASubscription) {
+    int serial = 1;
+
+    radio->getCDMASubscription(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getDeviceIdentity() for the response returned.
+ */
+TEST_F(RadioHidlTest, getDeviceIdentity) {
+    int serial = 1;
+
+    radio->getDeviceIdentity(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.exitEmergencyCallbackMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, exitEmergencyCallbackMode) {
+    int serial = 1;
+
+    radio->exitEmergencyCallbackMode(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getCdmaSubscriptionSource() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCdmaSubscriptionSource) {
+    int serial = 1;
+
+    radio->getCdmaSubscriptionSource(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getVoiceRadioTechnology() for the response returned.
+ */
+TEST_F(RadioHidlTest, getVoiceRadioTechnology) {
+    int serial = 1;
+
+    radio->getVoiceRadioTechnology(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getCellInfoList() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCellInfoList) {
+    int serial = 1;
+
+    radio->getCellInfoList(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setCellInfoListRate() for the response returned.
+ */
+TEST_F(RadioHidlTest, setCellInfoListRate) {
+    int serial = 1;
+
+    // TODO(sanketpadawe): RIL crashes with value of rate = 10
+    radio->setCellInfoListRate(++serial, 0);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.nvReadItem() for the response returned.
+ */
+TEST_F(RadioHidlTest, nvReadItem) {
+    int serial = 1;
+
+    radio->nvReadItem(++serial, NvItem::LTE_BAND_ENABLE_25);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.nvWriteItem() for the response returned.
+ */
+TEST_F(RadioHidlTest, nvWriteItem) {
+    int serial = 1;
+    NvWriteItem item;
+    memset(&item, 0, sizeof(item));
+    item.value = hidl_string();
+
+    radio->nvWriteItem(++serial, item);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.nvWriteCdmaPrl() for the response returned.
+ */
+TEST_F(RadioHidlTest, nvWriteCdmaPrl) {
+    int serial = 1;
+    std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
+
+    radio->nvWriteCdmaPrl(++serial, hidl_vec<uint8_t>(prl));
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.nvResetConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, nvResetConfig) {
+    int serial = 1;
+
+    radio->nvResetConfig(++serial, ResetNvType::RELOAD);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setUiccSubscription() for the response returned.
+ */
+TEST_F(RadioHidlTest, setUiccSubscription) {
+    int serial = 1;
+    SelectUiccSub item;
+    memset(&item, 0, sizeof(item));
+
+    radio->setUiccSubscription(++serial, item);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getHardwareConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, getHardwareConfig) {
+    int serial = 1;
+
+    radio->getHardwareConfig(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.requestShutdown() for the response returned.
+ */
+TEST_F(RadioHidlTest, requestShutdown) {
+    int serial = 1;
+
+    radio->requestShutdown(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getRadioCapability() for the response returned.
+ */
+TEST_F(RadioHidlTest, getRadioCapability) {
+    int serial = 1;
+
+    radio->getRadioCapability(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setRadioCapability() for the response returned.
+ */
+TEST_F(RadioHidlTest, setRadioCapability) {
+    int serial = 1;
+    RadioCapability rc;
+    memset(&rc, 0, sizeof(rc));
+    rc.logicalModemUuid = hidl_string();
+
+    radio->setRadioCapability(++serial, rc);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.startLceService() for the response returned.
+ */
+TEST_F(RadioHidlTest, startLceService) {
+    int serial = 1;
+
+    radio->startLceService(++serial, 5, true);
+    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(radioRsp->rspInfo.error == RadioError::NONE
+                || radioRsp->rspInfo.error == RadioError::LCE_NOT_SUPPORTED);
+    }
+}
+
+/*
+ * Test IRadio.stopLceService() for the response returned.
+ */
+TEST_F(RadioHidlTest, stopLceService) {
+    int serial = 1;
+
+    radio->stopLceService(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE
+                || radioRsp->rspInfo.error == RadioError::LCE_NOT_SUPPORTED);
+    }
+}
+
+/*
+ * Test IRadio.pullLceData() for the response returned.
+ */
+TEST_F(RadioHidlTest, pullLceData) {
+    int serial = 1;
+
+    radio->pullLceData(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE
+                || radioRsp->rspInfo.error == RadioError::LCE_NOT_SUPPORTED);
+    }
+}
+
+/*
+ * Test IRadio.getModemActivityInfo() for the response returned.
+ */
+TEST_F(RadioHidlTest, getModemActivityInfo) {
+    int serial = 1;
+
+    radio->getModemActivityInfo(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setAllowedCarriers() for the response returned.
+ */
+TEST_F(RadioHidlTest, setAllowedCarriers) {
+    int serial = 1;
+    CarrierRestrictions carriers;
+    memset(&carriers, 0, sizeof(carriers));
+    carriers.allowedCarriers.resize(1);
+    carriers.excludedCarriers.resize(0);
+    carriers.allowedCarriers[0].mcc = hidl_string();
+    carriers.allowedCarriers[0].mnc = hidl_string();
+    carriers.allowedCarriers[0].matchType = CarrierMatchType::ALL;
+    carriers.allowedCarriers[0].matchData = hidl_string();
+
+    radio->setAllowedCarriers(++serial, false, carriers);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.getAllowedCarriers() for the response returned.
+ */
+TEST_F(RadioHidlTest, getAllowedCarriers) {
+    int serial = 1;
+
+    radio->getAllowedCarriers(++serial);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.sendDeviceState() for the response returned.
+ */
+TEST_F(RadioHidlTest, sendDeviceState) {
+    int serial = 1;
+
+    radio->sendDeviceState(++serial, DeviceStateType::POWER_SAVE_MODE, true);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setIndicationFilter() for the response returned.
+ */
+TEST_F(RadioHidlTest, setIndicationFilter) {
+    int serial = 1;
+
+    radio->setIndicationFilter(++serial, 1);
+    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(radioRsp->rspInfo.error == RadioError::NONE);
+    }
+}
+
+/*
+ * Test IRadio.setSimCardPower() for the response returned.
+ */
+TEST_F(RadioHidlTest, setSimCardPower) {
+    int serial = 1;
+
+    radio->setSimCardPower(++serial, true);
+    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(radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
+    }
+}
\ No newline at end of file
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
index 5bf7ae2..54ae7c0 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
@@ -34,12 +34,11 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::INVALID_STATE, radioRsp->rspInfo.error);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INVALID_STATE);
         EXPECT_EQ(0, radioRsp->sendSmsResult.errorCode);
-    } else {
-        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
-        EXPECT_EQ("", radioRsp->sendSmsResult.ackPDU);
-        EXPECT_EQ(-1, radioRsp->sendSmsResult.errorCode);
     }
 }
 
@@ -61,11 +60,10 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::INVALID_STATE, radioRsp->rspInfo.error);
-    } else {
-        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
-        EXPECT_EQ("", radioRsp->sendSmsResult.ackPDU);
-        EXPECT_EQ(-1, radioRsp->sendSmsResult.errorCode);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INVALID_STATE);
     }
 }
 
@@ -84,9 +82,7 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::INVALID_STATE, radioRsp->rspInfo.error);
-    } else {
-        // TODO(shuoq): Will test right behavior when inserted sim card is considered
+        EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
     }
 }
 
@@ -106,8 +102,6 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         // TODO(shuoq): Will add error check when we know the expected error from QC
-    } else {
-        // TODO(shuoq): Will test right behavior when inserted sim card is considered
     }
 }
 
@@ -148,9 +142,10 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        // TODO(shuoq): Will add error check when we know the expected error from QC
-    } else {
-        // TODO(shuoq): radioRsp->sendSmsResult needs to be investigated when Sim card is in
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INVALID_STATE);
     }
 }
 
@@ -173,8 +168,6 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         EXPECT_EQ(RadioError::NO_SMS_TO_ACK, radioRsp->rspInfo.error);
-    } else {
-        EXPECT_EQ(RadioError::NO_SMS_TO_ACK, radioRsp->rspInfo.error);
     }
 }
 
@@ -224,9 +217,6 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
-    } else {
-        EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
-        // TODO(shuoq): radioRsp->sendSmsResult needs to be investigated when sim card is in
     }
 }
 
@@ -243,10 +233,11 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        // TODO(shuoq): Will add error check when we know the expected error from QC
-    } else {
-        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
-        // TODO(shuoq): radioRsp->smscAddress needs to be investigated when Sim card is in
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INVALID_STATE
+                || radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE);
     }
 }
 
@@ -265,8 +256,6 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         EXPECT_EQ(RadioError::INVALID_SMS_FORMAT, radioRsp->rspInfo.error);
-    } else {
-        EXPECT_EQ(RadioError::INVALID_SMS_FORMAT, radioRsp->rspInfo.error);
     }
 }
 
@@ -287,9 +276,10 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        // TODO(shuoq): Will add error check when we know the expected error from QC
-    } else {
-        // TODO(shuoq): radioRsp->writeSmsToSimIndex needs to be investigated when Sim card is in
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE
+                || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
     }
 }
 
@@ -307,9 +297,10 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        // TODO(shuoq): Will add error check when we know the expected error from QC
-    } else {
-        EXPECT_EQ(RadioError::NO_SUCH_ENTRY, radioRsp->rspInfo.error);
+        EXPECT_EQ(RadioError::INVALID_SMS_FORMAT, radioRsp->rspInfo.error);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR);
     }
 }
 
@@ -355,9 +346,10 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        // TODO(shuoq): Will add error check when we know the expected error from QC
-    } else {
-        // TODO(shuoq): radioRsp->writeSmsToRuimIndex needs to be investigated when sim card is in
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE
+                || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
     }
 }
 
@@ -404,9 +396,9 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        // TODO(shuoq): Will add error check when we know the expected error from QC
-    } else {
-        // TODO(shuoq): Will test right behavior when inserted sim card is considered
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR);
     }
 }
 
@@ -424,8 +416,9 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        // TODO(shuoq): Will add error check when we know the expected error from QC
-    } else {
-        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+                || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+                || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+                || radioRsp->rspInfo.error == RadioError::INVALID_STATE);
     }
 }
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
new file mode 100644
index 0000000..f6d576d
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
@@ -0,0 +1,153 @@
+/*
+ * 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<radio_hidl_hal_utils.h>
+
+using namespace ::android::hardware::radio::V1_0;
+
+/*
+ * Test IRadio.sendEnvelope() for the response returned.
+ */
+TEST_F(RadioHidlTest, sendEnvelope) {
+    int serial = 0;
+
+    // Test with sending empty string
+    std::string content = "";
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+
+    // Test with sending random string
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.sendTerminalResponseToSim() for the response returned.
+ */
+TEST_F(RadioHidlTest, sendTerminalResponseToSim) {
+    int serial = 0;
+
+    // Test with sending empty string
+    std::string commandResponse = "";
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+
+    // 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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.handleStkCallSetupRequestFromSim() for the response returned.
+ */
+TEST_F(RadioHidlTest, handleStkCallSetupRequestFromSim) {
+    int serial = 0;
+    bool accept = false;
+
+    radio->handleStkCallSetupRequestFromSim(++serial, accept);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.reportStkServiceIsRunning() for the response returned.
+ */
+TEST_F(RadioHidlTest, reportStkServiceIsRunning) {
+    int serial = 0;
+
+    radio->reportStkServiceIsRunning(++serial);
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+}
+
+/*
+ * Test IRadio.sendEnvelopeWithStatus() for the response returned with empty string.
+ */
+TEST_F(RadioHidlTest, sendEnvelopeWithStatus) {
+    int serial = 0;
+
+    // Test with sending empty string
+    std::string contents = "";
+
+    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) {
+        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+    }
+
+    // Test with sending random string
+    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_FALSE(RadioError::NONE == radioRsp->rspInfo.error);
+    }
+}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_utils.h b/radio/1.0/vts/functional/radio_hidl_hal_utils.h
index bb693ac..126ad0d 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/radio_hidl_hal_utils.h
@@ -32,6 +32,7 @@
 using ::android::hardware::radio::V1_0::CardState;
 using ::android::hardware::radio::V1_0::Call;
 using ::android::hardware::radio::V1_0::CallForwardInfo;
+using ::android::hardware::radio::V1_0::CarrierMatchType;
 using ::android::hardware::radio::V1_0::CarrierRestrictions;
 using ::android::hardware::radio::V1_0::CdmaRoamingType;
 using ::android::hardware::radio::V1_0::CdmaBroadcastSmsConfigInfo;
@@ -39,6 +40,7 @@
 using ::android::hardware::radio::V1_0::CellInfo;
 using ::android::hardware::radio::V1_0::ClipStatus;
 using ::android::hardware::radio::V1_0::DataRegStateResult;
+using ::android::hardware::radio::V1_0::DeviceStateType;
 using ::android::hardware::radio::V1_0::Dial;
 using ::android::hardware::radio::V1_0::GsmBroadcastSmsConfigInfo;
 using ::android::hardware::radio::V1_0::HardwareConfig;
@@ -54,6 +56,8 @@
 using ::android::hardware::radio::V1_0::LceDataInfo;
 using ::android::hardware::radio::V1_0::LceStatusInfo;
 using ::android::hardware::radio::V1_0::NeighboringCell;
+using ::android::hardware::radio::V1_0::NvItem;
+using ::android::hardware::radio::V1_0::NvWriteItem;
 using ::android::hardware::radio::V1_0::OperatorInfo;
 using ::android::hardware::radio::V1_0::PreferredNetworkType;
 using ::android::hardware::radio::V1_0::RadioBandMode;
@@ -61,6 +65,8 @@
 using ::android::hardware::radio::V1_0::RadioResponseType;
 using ::android::hardware::radio::V1_0::RadioTechnology;
 using ::android::hardware::radio::V1_0::RadioTechnologyFamily;
+using ::android::hardware::radio::V1_0::ResetNvType;
+using ::android::hardware::radio::V1_0::SelectUiccSub;
 using ::android::hardware::radio::V1_0::SendSmsResult;
 using ::android::hardware::radio::V1_0::SetupDataCallResult;
 using ::android::hardware::radio::V1_0::SignalStrength;
@@ -69,11 +75,12 @@
 using ::android::hardware::radio::V1_0::VoiceRegStateResult;
 
 using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::sp;
 
-#define TIMEOUT_PERIOD 20
+#define TIMEOUT_PERIOD 40
 
 class RadioHidlTest;
 extern CardStatus cardStatus;
diff --git a/radio/1.0/vts/functional/radio_response.cpp b/radio/1.0/vts/functional/radio_response.cpp
index 3db2dd1..8759003 100644
--- a/radio/1.0/vts/functional/radio_response.cpp
+++ b/radio/1.0/vts/functional/radio_response.cpp
@@ -72,7 +72,9 @@
 }
 
 Return<void> RadioResponse::supplyNetworkDepersonalizationResponse(
-        const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) {
+        const RadioResponseInfo& info, int32_t /*remainingRetries*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -147,28 +149,38 @@
 }
 
 Return<void> RadioResponse::getSignalStrengthResponse(
-        const RadioResponseInfo& /*info*/, const SignalStrength& /*sig_strength*/) {
+        const RadioResponseInfo& info, const SignalStrength& /*sig_strength*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getVoiceRegistrationStateResponse(
-        const RadioResponseInfo& /*info*/, const VoiceRegStateResult& /*voiceRegResponse*/) {
+        const RadioResponseInfo& info, const VoiceRegStateResult& /*voiceRegResponse*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getDataRegistrationStateResponse(
-        const RadioResponseInfo& /*info*/, const DataRegStateResult& /*dataRegResponse*/) {
+        const RadioResponseInfo& info, const DataRegStateResult& /*dataRegResponse*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getOperatorResponse(
-        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*longName*/,
+        const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*longName*/,
         const ::android::hardware::hidl_string& /*shortName*/,
         const ::android::hardware::hidl_string& /*numeric*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setRadioPowerResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setRadioPowerResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -195,7 +207,9 @@
 }
 
 Return<void> RadioResponse::setupDataCallResponse(
-        const RadioResponseInfo& /*info*/, const SetupDataCallResult& /*dcResponse*/) {
+        const RadioResponseInfo& info, const SetupDataCallResult& /*dcResponse*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -219,12 +233,16 @@
     return Void();
 }
 
-Return<void> RadioResponse::getClirResponse(const RadioResponseInfo& /*info*/, int32_t /*n*/,
+Return<void> RadioResponse::getClirResponse(const RadioResponseInfo& info, int32_t /*n*/,
         int32_t /*m*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setClirResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setClirResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -267,42 +285,58 @@
     return Void();
 }
 
-Return<void> RadioResponse::deactivateDataCallResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::deactivateDataCallResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::getFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::getFacilityLockForAppResponse(const RadioResponseInfo& info,
         int32_t /*response*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::setFacilityLockForAppResponse(const RadioResponseInfo& info,
         int32_t /*retry*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setBarringPasswordResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setBarringPasswordResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getNetworkSelectionModeResponse(
-        const RadioResponseInfo& /*info*/, bool /*manual*/) {
+        const RadioResponseInfo& info, bool /*manual*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::setNetworkSelectionModeAutomaticResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::setNetworkSelectionModeManualResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getAvailableNetworksResponse(
-        const RadioResponseInfo& /*info*/,
+        const RadioResponseInfo& info,
         const ::android::hardware::hidl_vec<OperatorInfo>& /*networkInfos*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -321,7 +355,9 @@
 }
 
 Return<void> RadioResponse::getBasebandVersionResponse(
-        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*version*/) {
+        const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*version*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -343,14 +379,18 @@
     return Void();
 }
 
-Return<void> RadioResponse::getClipResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::getClipResponse(const RadioResponseInfo& info,
         ClipStatus /*status*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getDataCallListResponse(
-        const RadioResponseInfo& /*info*/,
+        const RadioResponseInfo& info,
         const ::android::hardware::hidl_vec<SetupDataCallResult>& /*dcResponse*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -367,7 +407,9 @@
 }
 
 Return<void> RadioResponse::setSuppServiceNotificationsResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -386,27 +428,37 @@
     return Void();
 }
 
-Return<void> RadioResponse::setBandModeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setBandModeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getAvailableBandModesResponse(
-        const RadioResponseInfo& /*info*/,
+        const RadioResponseInfo& info,
         const ::android::hardware::hidl_vec<RadioBandMode>& /*bandModes*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::sendEnvelopeResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::sendEnvelopeResponse(const RadioResponseInfo& info,
         const ::android::hardware::hidl_string& /*commandResponse*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::sendTerminalResponseToSimResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::sendTerminalResponseToSimResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::handleStkCallSetupRequestFromSimResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -416,23 +468,31 @@
     return Void();
 }
 
-Return<void> RadioResponse::setPreferredNetworkTypeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setPreferredNetworkTypeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getPreferredNetworkTypeResponse(
-        const RadioResponseInfo& /*info*/, PreferredNetworkType /*nw_type*/) {
+        const RadioResponseInfo& info, PreferredNetworkType /*nw_type*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getNeighboringCidsResponse(
-        const RadioResponseInfo& /*info*/,
+        const RadioResponseInfo& info,
         const ::android::hardware::hidl_vec<NeighboringCell>& /*cells*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::setLocationUpdatesResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -440,30 +500,42 @@
     return Void();
 }
 
-Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getCdmaRoamingPreferenceResponse(
-        const RadioResponseInfo& /*info*/, CdmaRoamingType /*type*/) {
+        const RadioResponseInfo& info, CdmaRoamingType /*type*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setTTYModeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setTTYModeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::getTTYModeResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::getTTYModeResponse(const RadioResponseInfo& info,
         TtyMode /*mode*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getPreferredVoicePrivacyResponse(
-        const RadioResponseInfo& /*info*/, bool /*enable*/) {
+        const RadioResponseInfo& info, bool /*enable*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -493,39 +565,53 @@
 }
 
 Return<void> RadioResponse::getGsmBroadcastConfigResponse(
-        const RadioResponseInfo& /*info*/,
+        const RadioResponseInfo& info,
         const ::android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setGsmBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setGsmBroadcastConfigResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setGsmBroadcastActivationResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setGsmBroadcastActivationResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getCdmaBroadcastConfigResponse(
-        const RadioResponseInfo& /*info*/,
+        const RadioResponseInfo& info,
         const ::android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setCdmaBroadcastActivationResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setCdmaBroadcastActivationResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getCDMASubscriptionResponse(
-        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*mdn*/,
+        const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*mdn*/,
         const ::android::hardware::hidl_string& /*hSid*/,
         const ::android::hardware::hidl_string& /*hNid*/,
         const ::android::hardware::hidl_string& /*min*/,
         const ::android::hardware::hidl_string& /*prl*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -545,14 +631,18 @@
 }
 
 Return<void> RadioResponse::getDeviceIdentityResponse(
-        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imei*/,
+        const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*imei*/,
         const ::android::hardware::hidl_string& /*imeisv*/,
         const ::android::hardware::hidl_string& /*esn*/,
         const ::android::hardware::hidl_string& /*meid*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -576,17 +666,23 @@
     return Void();
 }
 
-Return<void> RadioResponse::reportStkServiceIsRunningResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::reportStkServiceIsRunningResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getCdmaSubscriptionSourceResponse(
-        const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) {
+        const RadioResponseInfo& info, CdmaSubscriptionSource /*source*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::requestIsimAuthenticationResponse(
-        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*response*/) {
+        const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*response*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -598,32 +694,44 @@
 }
 
 Return<void> RadioResponse::sendEnvelopeWithStatusResponse(
-        const RadioResponseInfo& /*info*/, const IccIoResult& /*iccIo*/) {
+        const RadioResponseInfo& info, const IccIoResult& /*iccIo*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getVoiceRadioTechnologyResponse(
-        const RadioResponseInfo& /*info*/, RadioTechnology /*rat*/) {
+        const RadioResponseInfo& info, RadioTechnology /*rat*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getCellInfoListResponse(
-        const RadioResponseInfo& /*info*/,
+        const RadioResponseInfo& info,
         const ::android::hardware::hidl_vec<CellInfo>& /*cellInfo*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setCellInfoListRateResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setCellInfoListRateResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setInitialAttachApnResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setInitialAttachApnResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getImsRegistrationStateResponse(
-        const RadioResponseInfo& /*info*/, bool /*isRegistered*/,
+        const RadioResponseInfo& info, bool /*isRegistered*/,
         RadioTechnologyFamily /*ratFamily*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -667,33 +775,47 @@
 }
 
 Return<void> RadioResponse::nvReadItemResponse(
-        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*result*/) {
+        const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*result*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::nvWriteItemResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::nvWriteItemResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::nvResetConfigResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::nvResetConfigResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setUiccSubscriptionResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setUiccSubscriptionResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::setDataAllowedResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setDataAllowedResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getHardwareConfigResponse(
-        const RadioResponseInfo& /*info*/,
+        const RadioResponseInfo& info,
         const ::android::hardware::hidl_vec<HardwareConfig>& /*config*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
@@ -705,67 +827,93 @@
     return Void();
 }
 
-Return<void> RadioResponse::setDataProfileResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setDataProfileResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioResponse::requestShutdownResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::requestShutdownResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getRadioCapabilityResponse(
-        const RadioResponseInfo& /*info*/, const RadioCapability& /*rc*/) {
+        const RadioResponseInfo& info, const RadioCapability& /*rc*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::setRadioCapabilityResponse(
-        const RadioResponseInfo& /*info*/, const RadioCapability& /*rc*/) {
+        const RadioResponseInfo& info, const RadioCapability& /*rc*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::startLceServiceResponse(
-        const RadioResponseInfo& /*info*/, const LceStatusInfo& /*statusInfo*/) {
+        const RadioResponseInfo& info, const LceStatusInfo& /*statusInfo*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::stopLceServiceResponse(
-        const RadioResponseInfo& /*info*/, const LceStatusInfo& /*statusInfo*/) {
+        const RadioResponseInfo& info, const LceStatusInfo& /*statusInfo*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::pullLceDataResponse(
-        const RadioResponseInfo& /*info*/, const LceDataInfo& /*lceInfo*/) {
+        const RadioResponseInfo& info, const LceDataInfo& /*lceInfo*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getModemActivityInfoResponse(
-        const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) {
+        const RadioResponseInfo& info, const ActivityStatsInfo& /*activityInfo*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::setAllowedCarriersResponse(
-        const RadioResponseInfo& /*info*/, int32_t /*numAllowed*/) {
+        const RadioResponseInfo& info, int32_t /*numAllowed*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::getAllowedCarriersResponse(
-        const RadioResponseInfo& /*info*/, bool /*allAllowed*/,
+        const RadioResponseInfo& info, bool /*allAllowed*/,
         const CarrierRestrictions& /*carriers*/) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::sendDeviceStateResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::setIndicationFilterResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
 Return<void> RadioResponse::setSimCardPowerResponse(
-        const RadioResponseInfo& /*info*/) {
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
diff --git a/sensors/1.0/default/Sensors.cpp b/sensors/1.0/default/Sensors.cpp
index 2457310..1100dd6 100644
--- a/sensors/1.0/default/Sensors.cpp
+++ b/sensors/1.0/default/Sensors.cpp
@@ -97,6 +97,15 @@
     // is considered optional.
     CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3);
 
+    if (getHalDeviceVersion() == SENSORS_DEVICE_API_VERSION_1_4) {
+        if (mSensorDevice->inject_sensor_data == nullptr) {
+            LOG(ERROR) << "HAL specifies version 1.4, but does not implement inject_sensor_data()";
+        }
+        if (mSensorModule->set_operation_mode == nullptr) {
+            LOG(ERROR) << "HAL specifies version 1.4, but does not implement set_operation_mode()";
+        }
+    }
+
     mInitCheck = OK;
 }
 
@@ -132,6 +141,10 @@
 }
 
 Return<Result> Sensors::setOperationMode(OperationMode mode) {
+    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4
+            || mSensorModule->set_operation_mode == nullptr) {
+        return Result::INVALID_OPERATION;
+    }
     return ResultFromStatus(mSensorModule->set_operation_mode((uint32_t)mode));
 }
 
@@ -236,7 +249,8 @@
 }
 
 Return<Result> Sensors::injectSensorData(const Event& event) {
-    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
+    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4
+            || mSensorDevice->inject_sensor_data == nullptr) {
         return Result::INVALID_OPERATION;
     }
 
diff --git a/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp b/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp
index 0ef4063..3fbef18 100644
--- a/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp
+++ b/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp
@@ -40,7 +40,6 @@
 using ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw;
 using ::android::hardware::soundtrigger::V2_0::ISoundTriggerHwCallback;
 using ::android::hardware::Return;
-using ::android::hardware::Status;
 using ::android::hardware::Void;
 using ::android::sp;
 
diff --git a/tests/Android.bp b/tests/Android.bp
index 6606d94..31dc75e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -23,4 +23,5 @@
     "versioning/1.0",
     "versioning/2.2",
     "versioning/2.3",
+    "versioning/2.4",
 ]
diff --git a/tests/extension/light/2.0/Android.bp b/tests/extension/light/2.0/Android.bp
index 5203da6..123bea1 100644
--- a/tests/extension/light/2.0/Android.bp
+++ b/tests/extension/light/2.0/Android.bp
@@ -51,6 +51,7 @@
         "libutils",
         "libcutils",
         "android.hardware.light@2.0",
+        "android.hidl.base@1.0",
     ],
     export_shared_lib_headers: [
         "libhidlbase",
@@ -58,5 +59,6 @@
         "libhwbinder",
         "libutils",
         "android.hardware.light@2.0",
+        "android.hidl.base@1.0",
     ],
 }
diff --git a/tests/versioning/2.3/Android.bp b/tests/versioning/2.3/Android.bp
index 122c484..3cc2076 100644
--- a/tests/versioning/2.3/Android.bp
+++ b/tests/versioning/2.3/Android.bp
@@ -63,6 +63,7 @@
         "libcutils",
         "android.hardware.tests.versioning@1.0",
         "android.hardware.tests.versioning@2.2",
+        "android.hidl.base@1.0",
     ],
     export_shared_lib_headers: [
         "libhidlbase",
@@ -71,5 +72,6 @@
         "libutils",
         "android.hardware.tests.versioning@1.0",
         "android.hardware.tests.versioning@2.2",
+        "android.hidl.base@1.0",
     ],
 }
diff --git a/tests/versioning/2.4/Android.bp b/tests/versioning/2.4/Android.bp
new file mode 100644
index 0000000..9d8303c
--- /dev/null
+++ b/tests/versioning/2.4/Android.bp
@@ -0,0 +1,63 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.tests.versioning@2.4_hal",
+    srcs: [
+        "IFoo.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.tests.versioning@2.4_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.versioning@2.4",
+    srcs: [
+        ":android.hardware.tests.versioning@2.4_hal",
+    ],
+    out: [
+        "android/hardware/tests/versioning/2.4/FooAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.tests.versioning@2.4_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.versioning@2.4",
+    srcs: [
+        ":android.hardware.tests.versioning@2.4_hal",
+    ],
+    out: [
+        "android/hardware/tests/versioning/2.4/IFoo.h",
+        "android/hardware/tests/versioning/2.4/IHwFoo.h",
+        "android/hardware/tests/versioning/2.4/BnHwFoo.h",
+        "android/hardware/tests/versioning/2.4/BpHwFoo.h",
+        "android/hardware/tests/versioning/2.4/BsFoo.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.tests.versioning@2.4",
+    generated_sources: ["android.hardware.tests.versioning@2.4_genc++"],
+    generated_headers: ["android.hardware.tests.versioning@2.4_genc++_headers"],
+    export_generated_headers: ["android.hardware.tests.versioning@2.4_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.tests.versioning@2.2",
+        "android.hardware.tests.versioning@2.3",
+        "android.hidl.base@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.tests.versioning@2.2",
+        "android.hardware.tests.versioning@2.3",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/tests/versioning/2.4/Android.mk b/tests/versioning/2.4/Android.mk
new file mode 100644
index 0000000..e41397f
--- /dev/null
+++ b/tests/versioning/2.4/Android.mk
@@ -0,0 +1,80 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.tests.versioning@2.4-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hardware.tests.versioning@2.2-java \
+    android.hardware.tests.versioning@2.3-java \
+    android.hidl.base@1.0-java \
+
+
+#
+# Build IFoo.hal
+#
+GEN := $(intermediates)/android/hardware/tests/versioning/V2_4/IFoo.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IFoo.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.tests.versioning@2.4::IFoo
+
+$(GEN): $(LOCAL_PATH)/IFoo.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.tests.versioning@2.4-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android.hardware.tests.versioning@2.2-java-static \
+    android.hardware.tests.versioning@2.3-java-static \
+    android.hidl.base@1.0-java-static \
+
+
+#
+# Build IFoo.hal
+#
+GEN := $(intermediates)/android/hardware/tests/versioning/V2_4/IFoo.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IFoo.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.tests.versioning@2.4::IFoo
+
+$(GEN): $(LOCAL_PATH)/IFoo.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/versioning/2.4/IFoo.hal b/tests/versioning/2.4/IFoo.hal
new file mode 100644
index 0000000..358b56f
--- /dev/null
+++ b/tests/versioning/2.4/IFoo.hal
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package android.hardware.tests.versioning@2.4;
+
+import @2.3::IFoo;
+
+// Must extend @2.3::IFoo.
+interface IFoo extends @2.3::IFoo {
+
+};
diff --git a/update-makefiles.sh b/update-makefiles.sh
index d0cb91c..88cc97b 100755
--- a/update-makefiles.sh
+++ b/update-makefiles.sh
@@ -1,52 +1,8 @@
 #!/bin/bash
 
-if [ ! -d hardware/interfaces ] ; then
-  echo "Where is hardware/interfaces?";
-  exit 1;
-fi
+source system/tools/hidl/update-makefiles-helper.sh
 
-if [ ! -d system/libhidl/transport ] ; then
-  echo "Where is system/libhidl/transport?";
-  exit 1;
-fi
+do_makefiles_update \
+  "android.hardware:hardware/interfaces" \
+  "android.hidl:system/libhidl/transport"
 
-packages=$(pushd hardware/interfaces > /dev/null; \
-           find . -type f -name \*.hal -exec dirname {} \; | sort -u | \
-           cut -c3- | \
-           awk -F'/' \
-                '{printf("android.hardware"); for(i=1;i<NF;i++){printf(".%s", $i);}; printf("@%s\n", $NF);}'; \
-           popd > /dev/null)
-
-for p in $packages; do
-  echo "Updating $p";
-  hidl-gen -Lmakefile -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport $p;
-  rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
-  hidl-gen -Landroidbp -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport $p;
-  rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
-done
-
-# subdirectories of hardware/interfaces which contain an Android.bp file
-android_dirs=$(find hardware/interfaces/*/     \
-              -name "Android.bp"               \
-              -printf "%h\n"                   \
-              | cut -d "/" -f1-3               \
-              | sort | uniq)
-
-echo "Updating Android.bp files."
-
-for bp_dir in $android_dirs; do
-  bp="$bp_dir/Android.bp"
-  # locations of Android.bp files in specific subdirectory of hardware/interfaces
-  android_bps=$(find $bp_dir                   \
-                -name "Android.bp"             \
-                ! -path $bp_dir/Android.bp     \
-                -printf "%h\n"                 \
-                | sort)
-
-  echo "// This is an autogenerated file, do not edit." > "$bp";
-  echo "subdirs = [" >> "$bp";
-  for a in $android_bps; do
-    echo "    \"${a#$bp_dir/}\"," >> "$bp";
-  done
-  echo "]" >> "$bp";
-done
diff --git a/usb/1.0/default/service.cpp b/usb/1.0/default/service.cpp
index b4db241..4605a4c 100644
--- a/usb/1.0/default/service.cpp
+++ b/usb/1.0/default/service.cpp
@@ -28,12 +28,11 @@
 using android::hardware::usb::V1_0::implementation::Usb;
 
 int main() {
-    const char instance[] = "usb_hal";
 
     android::sp<IUsb> service = new Usb();
 
     configureRpcThreadpool(1, true /*callerWillJoin*/);
-    service->registerAsService(instance);
+    service->registerAsService();
 
     ALOGI("USB HAL Ready.");
     joinRpcThreadpool();
diff --git a/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp b/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
index 54db8c2..ea6d4a9 100644
--- a/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
+++ b/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
@@ -47,8 +47,6 @@
 using ::android::hardware::Void;
 using ::android::sp;
 
-#define USB_SERVICE_NAME "usb_hal"
-
 // The main test class for the USB hidl HAL
 class UsbHidlTest : public ::testing::VtsHalHidlTargetTestBase {
  public:
@@ -97,7 +95,7 @@
 
   virtual void SetUp() override {
     ALOGI("Setup");
-    usb = ::testing::VtsHalHidlTargetTestBase::getService<IUsb>(USB_SERVICE_NAME);
+    usb = ::testing::VtsHalHidlTargetTestBase::getService<IUsb>();
     ASSERT_NE(usb, nullptr);
 
     usb_cb_2 = new UsbCallback(*this, 2);
diff --git a/vibrator/1.0/Android.mk b/vibrator/1.0/Android.mk
index 4e1ba6a..d921a7e 100644
--- a/vibrator/1.0/Android.mk
+++ b/vibrator/1.0/Android.mk
@@ -17,6 +17,25 @@
 
 
 #
+# Build types.hal (Effect)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Effect.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.vibrator@1.0::types.Effect
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (Status)
 #
 GEN := $(intermediates)/android/hardware/vibrator/V1_0/Status.java
@@ -73,6 +92,25 @@
 
 
 #
+# Build types.hal (Effect)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Effect.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.vibrator@1.0::types.Effect
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (Status)
 #
 GEN := $(intermediates)/android/hardware/vibrator/V1_0/Status.java
@@ -114,5 +152,39 @@
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.vibrator@1.0-java-constants
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Constants.java
+$(GEN): $(HIDL)
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/IVibrator.hal
+
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava-constants \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.vibrator@1.0
+
+$(GEN):
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+# Avoid dependency cycle of framework.jar -> this-library -> framework.jar
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-oj
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/vibrator/1.0/IVibrator.hal b/vibrator/1.0/IVibrator.hal
index 0a4ffca..757ad0d 100644
--- a/vibrator/1.0/IVibrator.hal
+++ b/vibrator/1.0/IVibrator.hal
@@ -17,7 +17,8 @@
 package android.hardware.vibrator@1.0;
 
 interface IVibrator {
-  /** Turn on vibrator
+  /**
+   * Turn on vibrator
    *
    * This function must only be called after the previous timeout has expired or
    * was canceled (through off()).
@@ -26,10 +27,46 @@
    */
   on(uint32_t timeoutMs) generates (Status vibratorOnRet);
 
-  /** Turn off vibrator
+  /**
+   * Turn off vibrator
    *
    * Cancel a previously-started vibration, if any.
    * @return vibratorOffRet whether vibrator command was successful or not.
    */
   off() generates (Status vibratorOffRet);
+
+  /**
+   * Returns whether the vibrator supports changes to its vibrational amplitude.
+   */
+  supportsAmplitudeControl() generates (bool supports);
+
+  /**
+   * Sets the motor's vibrational amplitude.
+   *
+   * Changes the force being produced by the underlying motor.
+   *
+   * @param amplitude The unitless force setting. Note that this number must
+   *                  be between 1 and 255, inclusive. If the motor does not
+   *                  have exactly 255 steps, it must do it's best to map it
+   *                  onto the number of steps it does have.
+   * @return status Whether the command was successful or not. Must return
+   *                Status::UNSUPPORTED_OPERATION if setting the amplitude is
+   *                not supported by the device.
+   */
+  setAmplitude(uint8_t amplitude) generates (Status status);
+
+  /**
+   * Fire off a predefined haptic event.
+   *
+   * @param event The type of haptic event to trigger.
+   * @return status Whether the effect was successfully performed or not. Must
+   *                return Status::UNSUPPORTED_OPERATION is the effect is not
+   *                supported.
+   * @return lengthMs The length of time the event is expected to take in
+   *                  milliseconds. This doesn't need to be perfectly accurate,
+   *                  but should be a reasonable approximation. Should be a
+   *                  positive, non-zero value if the returned status is
+   *                  Status::OK, and set to 0 otherwise.
+   */
+  perform(Effect effect, EffectStrength strength) generates (Status status, uint32_t lengthMs);
 };
diff --git a/vibrator/1.0/default/Vibrator.cpp b/vibrator/1.0/default/Vibrator.cpp
index 8c82bcd..19cf3dc 100644
--- a/vibrator/1.0/default/Vibrator.cpp
+++ b/vibrator/1.0/default/Vibrator.cpp
@@ -16,6 +16,8 @@
 
 #define LOG_TAG "VibratorService"
 
+#include <inttypes.h>
+
 #include <log/log.h>
 
 #include <hardware/hardware.h>
@@ -36,7 +38,7 @@
     int32_t ret = mDevice->vibrator_on(mDevice, timeout_ms);
     if (ret != 0) {
         ALOGE("on command failed : %s", strerror(-ret));
-        return Status::ERR;
+        return Status::UNKNOWN_ERROR;
     }
     return Status::OK;
 }
@@ -45,11 +47,24 @@
     int32_t ret = mDevice->vibrator_off(mDevice);
     if (ret != 0) {
         ALOGE("off command failed : %s", strerror(-ret));
-        return Status::ERR;
+        return Status::UNKNOWN_ERROR;
     }
     return Status::OK;
 }
 
+Return<bool> Vibrator::supportsAmplitudeControl()  {
+    return false;
+}
+
+Return<Status> Vibrator::setAmplitude(uint8_t) {
+    return Status::UNSUPPORTED_OPERATION;
+}
+
+Return<void> Vibrator::perform(Effect, EffectStrength, perform_cb _hidl_cb) {
+    _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
+    return Void();
+}
+
 IVibrator* HIDL_FETCH_IVibrator(const char * /*hal*/) {
     vibrator_device_t *vib_device;
     const hw_module_t *hw_module = nullptr;
diff --git a/vibrator/1.0/default/Vibrator.h b/vibrator/1.0/default/Vibrator.h
index 061b364..bea6ea8 100644
--- a/vibrator/1.0/default/Vibrator.h
+++ b/vibrator/1.0/default/Vibrator.h
@@ -26,23 +26,18 @@
 namespace V1_0 {
 namespace implementation {
 
-using ::android::hardware::vibrator::V1_0::IVibrator;
-using ::android::hardware::vibrator::V1_0::Status;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
 struct Vibrator : public IVibrator {
   Vibrator(vibrator_device_t *device);
 
   // Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
   Return<Status> on(uint32_t timeoutMs)  override;
   Return<Status> off()  override;
+  Return<bool> supportsAmplitudeControl() override;
+  Return<Status> setAmplitude(uint8_t amplitude) override;
+  Return<void> perform(Effect effect, EffectStrength strength, perform_cb _hidl_cb) override;
 
-  private:
-    vibrator_device_t    *mDevice;
+private:
+  vibrator_device_t    *mDevice;
 };
 
 extern "C" IVibrator* HIDL_FETCH_IVibrator(const char* name);
diff --git a/vibrator/1.0/types.hal b/vibrator/1.0/types.hal
index 8fc5683..a080c07 100644
--- a/vibrator/1.0/types.hal
+++ b/vibrator/1.0/types.hal
@@ -16,7 +16,33 @@
 
 package android.hardware.vibrator@1.0;
 
-enum Status: uint32_t {
-    OK             = 0,
-    ERR            = 1
+enum Status : uint32_t {
+    OK,
+    UNKNOWN_ERROR,
+    BAD_VALUE,
+    UNSUPPORTED_OPERATION
+};
+
+@export
+enum Effect : uint32_t {
+    /**
+     * A single click effect.
+     *
+     * This effect should produce a sharp, crisp click sensation.
+     */
+    CLICK,
+    /**
+     * A double click effect.
+     *
+     * This effect should produce two sequential sharp, crisp click sensations with a minimal
+     * amount of time between them.
+     */
+    DOUBLE_CLICK
+};
+
+@export
+enum EffectStrength : uint8_t {
+    LIGHT,
+    MEDIUM,
+    STRONG
 };
diff --git a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
index a978f2c..f415ad5 100644
--- a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
+++ b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
@@ -22,6 +22,8 @@
 #include <VtsHalHidlTargetTestBase.h>
 #include <unistd.h>
 
+using ::android::hardware::vibrator::V1_0::Effect;
+using ::android::hardware::vibrator::V1_0::EffectStrength;
 using ::android::hardware::vibrator::V1_0::IVibrator;
 using ::android::hardware::vibrator::V1_0::Status;
 using ::android::hardware::Return;
@@ -50,12 +52,49 @@
  private:
 };
 
+static void validatePerformEffect(Status status, uint32_t lengthMs) {
+  ASSERT_TRUE(status == Status::OK || status == Status::UNSUPPORTED_OPERATION);
+  if (status == Status::OK) {
+      ASSERT_GT(lengthMs, static_cast<uint32_t>(0));
+  } else {
+      ASSERT_EQ(lengthMs, static_cast<uint32_t>(0));
+  }
+}
+
 TEST_F(VibratorHidlTest, OnThenOffBeforeTimeout) {
   EXPECT_EQ(Status::OK, vibrator->on(2000));
   sleep(1);
   EXPECT_EQ(Status::OK, vibrator->off());
 }
 
+TEST_F(VibratorHidlTest, PerformEffect) {
+  vibrator->perform(Effect::CLICK, EffectStrength::MEDIUM, validatePerformEffect);
+  vibrator->perform(Effect::DOUBLE_CLICK, EffectStrength::LIGHT, validatePerformEffect);
+}
+
+TEST_F(VibratorHidlTest, ChangeVibrationalAmplitude) {
+  if (vibrator->supportsAmplitudeControl()) {
+    EXPECT_EQ(Status::OK, vibrator->setAmplitude(1));
+    EXPECT_EQ(Status::OK, vibrator->on(2000));
+    EXPECT_EQ(Status::OK, vibrator->setAmplitude(128));
+    sleep(1);
+    EXPECT_EQ(Status::OK, vibrator->setAmplitude(255));
+    sleep(1);
+  }
+}
+
+TEST_F(VibratorHidlTest, AmplitudeOutsideRangeFails) {
+  if (vibrator->supportsAmplitudeControl()) {
+    EXPECT_EQ(Status::BAD_VALUE, vibrator->setAmplitude(0));
+  }
+}
+
+TEST_F(VibratorHidlTest, SetAmplitudeReturnUnsupportedOperationIfNotSupported) {
+  if (!vibrator->supportsAmplitudeControl()) {
+    EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setAmplitude(1));
+  }
+}
+
 int main(int argc, char **argv) {
   ::testing::AddGlobalTestEnvironment(new VibratorHidlEnvironment);
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
index 5fc0228..ba57ba7 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -328,9 +328,8 @@
   wifi_error status = init_wifi_vendor_hal_func_table(&global_func_table_);
   if (status != WIFI_SUCCESS) {
     LOG(ERROR) << "Failed to initialize legacy hal function table";
-    return WIFI_ERROR_UNKNOWN;
   }
-  return WIFI_SUCCESS;
+  return status;
 }
 
 wifi_error WifiLegacyHal::start() {
diff --git a/wifi/supplicant/1.0/ISupplicantP2pIface.hal b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
index dc1388a..fb4323c 100644
--- a/wifi/supplicant/1.0/ISupplicantP2pIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
@@ -611,7 +611,7 @@
    *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
    *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
    */
-  setWfdDeviceInfo(uint8_t[8] info) generates (SupplicantStatus status);
+  setWfdDeviceInfo(uint8_t[6] info) generates (SupplicantStatus status);
 
   /**
    * Creates a NFC handover request message.
@@ -672,4 +672,15 @@
    */
   reportNfcHandoverInitiation(vec<uint8_t> select)
       generates (SupplicantStatus status);
+
+  /**
+   * Persist the current configuration to disk.
+   *
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+   *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+   */
+  saveConfig() generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.hal b/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.hal
index b6ee57f..8a54bf4 100644
--- a/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.hal
+++ b/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.hal
@@ -105,7 +105,7 @@
       MacAddress srcAddress, MacAddress p2pDeviceAddress,
       uint8_t[8] primaryDeviceType, string deviceName,
       bitfield<WpsConfigMethods> configMethods, uint8_t deviceCapabilities,
-      bitfield<P2pGroupCapabilityMask> groupCapabilities, uint8_t[8] wfdDeviceInfo);
+      bitfield<P2pGroupCapabilityMask> groupCapabilities, uint8_t[6] wfdDeviceInfo);
 
   /**
    * Used to indicate that a P2P device has been lost.
diff --git a/wifi/supplicant/1.0/ISupplicantP2pNetwork.hal b/wifi/supplicant/1.0/ISupplicantP2pNetwork.hal
index d32b47e..6ec7143 100644
--- a/wifi/supplicant/1.0/ISupplicantP2pNetwork.hal
+++ b/wifi/supplicant/1.0/ISupplicantP2pNetwork.hal
@@ -100,4 +100,34 @@
    * @return isGo true if group owner, false otherwise.
    */
   isGo() generates (SupplicantStatus status, bool isGo);
+
+  /**
+   * Set the list of P2P Clients in a persistent group (GO).
+   * This is a list of P2P Clients (P2P Device Address) that have joined
+   * the persistent group. This is maintained on the GO for persistent
+   * group entries (disabled == 2).
+   *
+   * @param clients MAC address of the clients.
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantP2ptusCode.FAILURE_UNKNOWN|,
+   *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+   */
+  setClientList(vec<MacAddress> clients) generates (SupplicantStatus status);
+
+  /**
+   * Get the list of P2P Clients in a persistent group (GO).
+   * This is a list of P2P Clients (P2P Device Address) that have joined
+   * the persistent group. This is maintained on the GO for persistent
+   * group entries (disabled == 2).
+   *
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantP2ptusCode.FAILURE_UNKNOWN|,
+   *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+   * @return clients MAC address of the clients.
+   */
+  getClientList() generates (SupplicantStatus status, vec<MacAddress> clients);
 };
diff --git a/wifi/supplicant/1.0/ISupplicantStaIface.hal b/wifi/supplicant/1.0/ISupplicantStaIface.hal
index 68eb179..f89017c 100644
--- a/wifi/supplicant/1.0/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaIface.hal
@@ -460,4 +460,19 @@
    *         |SupplicantStatusCode.FAILURE_UNKNOWN|
    */
   removeExtRadioWork(uint32_t id) generates (SupplicantStatus status);
+
+  /**
+   * Enable/Disable auto reconnect to networks.
+   * Use this to prevent wpa_supplicant from trying to connect to networks
+   * on its own.
+   *
+   * @param enable true to enable, false to disable.
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+   *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+   *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+   */
+  enableAutoReconnect(bool enable) generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
index 166ad96..173cce9 100644
--- a/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
@@ -346,6 +346,24 @@
   };
 
   /**
+   * BSSID change Reasons.
+   */
+  enum BssidChangeReason : uint8_t {
+    /**
+     * Started association with new bssid.
+     */
+    ASSOC_START = 0,
+    /**
+     * Completed association with new bssid.
+     */
+    ASSOC_COMPLETE = 1,
+    /**
+     * Dis-association with current bssid.
+     */
+    DISASSOC = 2
+  };
+
+  /**
    * Used to indicate that a new network has been added.
    *
    * @param id Network ID allocated to the corresponding network.
@@ -466,6 +484,16 @@
   oneway onEapFailure();
 
   /**
+   * Used to indicate the change of active bssid.
+   * This is useful to figure out when the driver/firmware roams to a bssid
+   * on its own.
+   *
+   * @param reason Reason why the bssid changed.
+   * @param bssid BSSID of the corresponding AP.
+   */
+  oneway onBssidChanged(BssidChangeReason reason, Bssid bssid);
+
+  /**
    * Used to indicate the success of a WPS connection attempt.
    */
   oneway onWpsEventSuccess();
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 c6cf01f..72a3c42 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
@@ -81,7 +81,7 @@
         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 {
+        const hidl_array<uint8_t, 6>& /* wfdDeviceInfo */) override {
         return Void();
     }
     Return<void> onDeviceLost(