Merge "IUsb uses "default" service name"
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/audio/common/2.0/types.hal b/audio/common/2.0/types.hal
index 93b898b..8760a58 100644
--- a/audio/common/2.0/types.hal
+++ b/audio/common/2.0/types.hal
@@ -672,7 +672,7 @@
     DIRECT_PCM = 0x2000,     // Audio stream containing PCM data that needs
                              // to pass through compress path for DSP post proc.
     MMAP_NOIRQ = 0x4000, // output operates in MMAP no IRQ mode.
-    VOIP_CALL_RX = 0x8000, // preferred output for VoIP calls.
+    VOIP_RX = 0x8000,    // preferred output for VoIP calls.
 };
 
 /*
@@ -689,7 +689,7 @@
     RAW          = 0x4,  // minimize signal processing
     SYNC         = 0x8,  // synchronize I/O streams
     MMAP_NOIRQ   = 0x10, // input operates in MMAP no IRQ mode.
-    VOIP_CALL_TX = 0x20, // preferred input for VoIP calls.
+    VOIP_TX      = 0x20, // preferred input for VoIP calls.
 };
 
 @export(name="audio_usage_t", value_prefix="AUDIO_USAGE_")
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/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/device/3.2/types.hal b/camera/device/3.2/types.hal
index fe1edbf..c7d38c1 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -151,6 +151,13 @@
      *      android.lens.opticalStabilizationMode (if it is supported)
      *      android.scaler.cropRegion
      *      android.statistics.faceDetectMode (if it is supported)
+     *   6. To reduce the amount of data passed across process boundaries at
+     *      high frame rate, within one batch, camera framework only propagates
+     *      the last shutter notify and the last capture results (including partial
+     *      results and final result) to the app. The shutter notifies and capture
+     *      results for the other requests in the batch are derived by
+     *      the camera framework. As a result, the HAL can return empty metadata
+     *      except for the last result in the batch.
      *
      * For more details about high speed stream requirements, see
      * android.control.availableHighSpeedVideoConfigurations and
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 58cb9f1..43c96ee 100644
--- a/configstore/1.0/ISurfaceFlingerConfigs.hal
+++ b/configstore/1.0/ISurfaceFlingerConfigs.hal
@@ -76,4 +76,24 @@
      * present fences.
      */
     presentTimeOffsetFromVSyncNs() generates(OptionalInt64 value);
+
+    /*
+     * Some hardware can do RGB->YUV conversion more efficiently in hardware
+     * controlled by HWC than in hardware controlled by the video encoder.
+     * This instruct VirtualDisplaySurface to use HWC for such conversion on
+     * 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);
 };
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.cpp b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
index 86e9b35..e8872e8 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
@@ -79,8 +89,29 @@
       return Void();
 }
 
-// Methods from ::android::hidl::base::V1_0::IBase follow.
+Return<void> SurfaceFlingerConfigs::useHwcForRGBtoYUV(useHwcForRGBtoYUV_cb _hidl_cb) {
+    bool value = false;
+#ifdef FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS
+    value = true;
+#endif
+    _hidl_cb({true, value});
+    LOG(INFO) << "SurfaceFlinger forceHwcForRGBtoYUV: " << value;
+    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();
+}
+
+// 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 8378383..bea1ab1 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.h
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.h
@@ -31,6 +31,9 @@
     Return<void> hasWideColorDisplay(hasWideColorDisplay_cb _hidl_cb) override;
     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;
 
     // 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 d824072..6e63fdc 100644
--- a/configstore/1.0/default/surfaceflinger.mk
+++ b/configstore/1.0/default/surfaceflinger.mk
@@ -34,3 +34,15 @@
 else
     LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=0
 endif
+
+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
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/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/renderscript/1.0/vts/functional/Android.bp b/renderscript/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..635e2e6
--- /dev/null
+++ b/renderscript/1.0/vts/functional/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "VtsHalRenderscriptV1_0TargetTest",
+    srcs: [
+        "VtsHalRenderscriptV1_0TargetTest.cpp",
+        "VtsCopyTests.cpp",
+        "VtsMiscellaneousTests.cpp",
+        "VtsScriptTests.cpp",
+        "bitcode.cpp",
+    ],
+    defaults: ["hidl_defaults"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.renderscript@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/renderscript/1.0/vts/functional/VtsCopyTests.cpp b/renderscript/1.0/vts/functional/VtsCopyTests.cpp
new file mode 100644
index 0000000..77217cb
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsCopyTests.cpp
@@ -0,0 +1,427 @@
+/*
+ * 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 "VtsHalRenderscriptV1_0TargetTest.h"
+
+/*
+ * This test creates a 1D Allocation with 128 Float Elements, and two float
+ * vector dataIn & dataOut. dataIn is pre-populated with data, and copied into
+ * the Allocation using allocation1DWrite. Then the Allocation is copied into
+ * dataOut with allocation1DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation1DWrite,
+ * allocation1DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, Simple1DCopyTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 128 x float1
+    Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+    // 128 x float1
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    std::vector<float> dataIn(128), dataOut(128);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+    context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
+    context->allocation1DRead(allocation, 0, 0, (uint32_t)dataOut.size(), (Ptr)dataOut.data(),
+                              (Size)dataOut.size()*sizeof(float));
+    bool same = std::all_of(dataOut.begin(), dataOut.end(),
+                            [](float x){ static int val = 0; return x == (float)val++; });
+    EXPECT_EQ(true, same);
+}
+
+/*
+ * This test creates a 2D Allocation with 128 * 128 Float Elements, and two
+ * float vector dataIn & dataOut. dataIn is pre-populated with data, and copied
+ * into the Allocation using allocation2DWrite. Then the Allocation is copied
+ * into dataOut with allocation2DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
+ * allocation2DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, Simple2DCopyTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 128 x 128 x float1
+    Type type = context->typeCreate(element, 128, 128, 0, false, false, YuvFormat::YUV_NONE);
+    // 128 x 128 x float1
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    std::vector<float> dataIn(128*128), dataOut(128*128);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+    context->allocation2DWrite(allocation, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 128, 128,
+                               _data, 0);
+    context->allocation2DRead(allocation, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 128, 128,
+                              (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float), 0);
+    bool same = std::all_of(dataOut.begin(), dataOut.end(),
+                            [](float x){ static int val = 0; return x == (float)val++; });
+    EXPECT_EQ(true, same);
+}
+
+/*
+ * This test creates a 3D Allocation with 32 * 32 * 32 Float Elements, and two
+ * float vector dataIn & dataOut. dataIn is pre-populated with data, and copied
+ * into the Allocation using allocation3DWrite. Then the Allocation is copied
+ * into dataOut with allocation3DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation3DWrite,
+ * allocation3DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, Simple3DCopyTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 32 x 32 x 32 x float1
+    Type type = context->typeCreate(element, 32, 32, 32, false, false, YuvFormat::YUV_NONE);
+    // 32 x 32 x 32 x float1
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    std::vector<float> dataIn(32*32*32), dataOut(32*32*32);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+    context->allocation3DWrite(allocation, 0, 0, 0, 0, 32, 32, 32, _data, 0);
+    context->allocation3DRead(allocation, 0, 0, 0, 0, 32, 32, 32, (Ptr)dataOut.data(),
+                              (Size)dataOut.size()*sizeof(float), 0);
+    bool same = std::all_of(dataOut.begin(), dataOut.end(),
+                            [](float x){ static int val = 0; return x == (float)val++; });
+    EXPECT_EQ(true, same);
+}
+
+/*
+ * This test creates a 2D Allocation with 512 * 512 Float Elements with
+ * allocationCreateFromBitmap, and two float vector dataIn & dataOut. dataIn is
+ * pre-populated with data, and copied into the Allocation using
+ * allocationCopyToBitmap. Then the Allocation is copied into dataOut with
+ * allocationRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateFromBitmap,
+ * allocationCopyToBitmap, allocationRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, SimpleBitmapTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 512 x 512 x float1
+    Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+    std::vector<float> dataIn(512*512), dataOut1(512*512), dataOut2(512*512);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+    // 512 x 512 x float1
+    Allocation allocation = context->allocationCreateFromBitmap(type,
+                                                                AllocationMipmapControl::NONE,
+                                                                _data,
+                                                                (int)AllocationUsageType::SCRIPT);
+    EXPECT_NE(allocation, Allocation(0));
+
+    context->allocationCopyToBitmap(allocation, (Ptr)dataOut1.data(),
+                                    (Size)dataOut1.size()*sizeof(float));
+    bool same1 = std::all_of(dataOut1.begin(), dataOut1.end(),
+                             [](float x){ static int val = 0; return x == (float)val++; });
+    EXPECT_EQ(true, same1);
+
+    context->allocationRead(allocation, (Ptr)dataOut2.data(), (Size)dataOut2.size()*sizeof(float));
+    bool same2 = std::all_of(dataOut2.begin(), dataOut2.end(),
+                             [](float x){ static int val = 0; return x == (float)val++; });
+    EXPECT_EQ(true, same2);
+}
+
+/*
+ * This test creates two 2D Allocations, one with 512 * 512 Float Elements, the
+ * other with 256 * 256 Float Elements. The larger Allocation is pre-populated
+ * with dataIn, and copied into the smaller Allocation using
+ * allocationCopy2DRange. Then the Allocation is copied into dataOut with
+ * allocationRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateFromBitmap,
+ * allocationCreateTyped, allocationCopy2DRange, allocationRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, AllocationCopy2DRangeTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 512 x 512 x float1
+    Type typeSrc = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+    // 256 x 256 x float1
+    Type typeDst = context->typeCreate(element, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
+    std::vector<float> dataIn(512*512), dataOut(256*256), expected(256*256);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+    // 512 x 512 x float1
+    Allocation allocSrc = context->allocationCreateFromBitmap(typeSrc,
+                                                              AllocationMipmapControl::NONE, _data,
+                                                              (int)AllocationUsageType::SCRIPT);
+    // 256 x 256 x float1
+    Allocation allocDst = context->allocationCreateTyped(typeDst, AllocationMipmapControl::NONE,
+                                                         (int)AllocationUsageType::SCRIPT,
+                                                         (Ptr)nullptr);
+    context->allocationCopy2DRange(allocDst, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
+                                   allocSrc, 128, 128, 0, AllocationCubemapFace::POSITIVE_X);
+    context->allocationRead(allocDst, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float));
+    for (int i = 0; i < 256; ++i) {
+        for (int j = 0; j < 256; ++j) {
+            expected[i*256 + j] = dataIn[(i+128)*512 + (j+128)];
+        }
+    }
+    EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates two 3D Allocations, one with 128 * 128 * 128 Float
+ * Elements, the other with 64 * 64 * 64 Float Elements. The larger Allocation
+ * is pre-populated with dataIn, and copied into the smaller Allocation using
+ * allocationCopy3DRange. Then the Allocation is copied into dataOut with
+ * allocationRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation3DWrite,
+ * allocationCopy3DRange, allocationRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, AllocationCopy3DRangeTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 128 x 128 x 128 x float1
+    Type typeSrc = context->typeCreate(element, 128, 128, 128, false, false, YuvFormat::YUV_NONE);
+    // 64 x 64 x 64 x float1
+    Type typeDst = context->typeCreate(element, 64, 64, 64, false, false, YuvFormat::YUV_NONE);
+    std::vector<float> dataIn(128*128*128), dataOut(64*64*64), expected(64*64*64);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+    // 512 x 512 x float1
+    Allocation allocSrc = context->allocationCreateTyped(typeSrc, AllocationMipmapControl::NONE,
+                                                         (int)AllocationUsageType::SCRIPT,
+                                                         (Ptr)nullptr);
+    // 256 x 256 x float1
+    Allocation allocDst = context->allocationCreateTyped(typeDst, AllocationMipmapControl::NONE,
+                                                         (int)AllocationUsageType::SCRIPT,
+                                                         (Ptr)nullptr);
+    context->allocation3DWrite(allocSrc, 0, 0, 0, 0, 128, 128, 128, _data, 128*sizeof(float));
+    context->allocationCopy3DRange(allocDst, 0, 0, 0, 0, 64, 64, 64, allocSrc, 32, 32, 32, 0);
+    context->allocationRead(allocDst, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float));
+    for (int i = 0; i < 64; ++i) {
+        for (int j = 0; j < 64; ++j) {
+            for (int k = 0; k < 64; ++k) {
+                expected[i*64*64 + j*64 + k] = dataIn[(i+32)*128*128 + (j+32)*128 + (k+32)];
+            }
+        }
+    }
+    EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates one 2D Allocations, one with 512 * 512 Float Elements, and
+ * one 2D AllocationAdapter with a window of 256 * 256 based on the Allocation.
+ * The Allocation is pre-populated with dataIn. Then the Allocation is copied
+ * into dataOut with allocationRead on the AllocationAdapter.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateFromBitmap,
+ * allocationAdapterCreate, allocationAdapterOffset, allocation2DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, SimpleAdapterTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 512 x 512 x float1
+    Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+    std::vector<float> dataIn(512*512), dataOut(256*256), expected;
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+    // 512 x 512 x float1
+    Allocation allocation = context->allocationCreateFromBitmap(type,
+                                                                AllocationMipmapControl::NONE,
+                                                                _data,
+                                                                (int)AllocationUsageType::SCRIPT);
+    // 256 x 256 x float1
+    Type subType = context->typeCreate(element, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
+    // 256 x 256 x float1
+    AllocationAdapter allocationAdapter = context->allocationAdapterCreate(subType, allocation);
+    EXPECT_NE(AllocationAdapter(0), allocationAdapter);
+
+    std::vector<uint32_t> offsets(9, 0);
+    offsets[0] = 128;
+    offsets[1] = 128;
+    hidl_vec<uint32_t> _offsets;
+    _offsets.setToExternal(offsets.data(), offsets.size());
+    // origin at (128,128)
+    context->allocationAdapterOffset(allocationAdapter, _offsets);
+
+    context->allocation2DRead(allocationAdapter, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256,
+                              256, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float), 0);
+    for (int i = 128; i < 128 + 256; ++i) {
+        for (int j = 128; j < 128 + 256; ++j) {
+            expected.push_back(i * 512 + j);
+        }
+    }
+    EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates one 2D Allocations, one with 64 * 64 USIGNED_8 Elements,
+ * and with AllocationMipmapControl::FULL. The Allocation is pre-populated with
+ * dataIn and the mipmaps are filled with allocationGenerateMipmaps. Then
+ * dataOut is then overridden with allocation2DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
+ * allocationGenerateMipmaps, allocationSyncAll, allocation2DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, SimpleMipmapTest) {
+    // uint8_t
+    Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+    // 64 x 64 x uint8_t
+    Type type = context->typeCreate(element, 64, 64, 0, true, false, YuvFormat::YUV_NONE);
+    std::vector<uint8_t> dataIn(64*64), dataOut(32*32), expected(32*32);
+    std::generate(dataIn.begin(), dataIn.end(),
+                  [](){ static int val = 0; return (uint8_t)(0xFF & val++); });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(uint8_t));
+    // 64 x 64 x uint8_t
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::FULL,
+                                                         (int)AllocationUsageType::SCRIPT,
+                                                         (Ptr)nullptr);
+    context->allocation2DWrite(allocation, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 64, 64,
+                               _data, 64*sizeof(uint8_t));
+    context->allocationGenerateMipmaps(allocation);
+    context->allocationSyncAll(allocation, AllocationUsageType::SCRIPT);
+    context->allocation2DRead(allocation, 0, 0, 1, AllocationCubemapFace::POSITIVE_X, 32, 32,
+                              (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint8_t),
+                              32*sizeof(uint8_t));
+    for (int i = 0; i < 32; ++i) {
+        for (int j = 0; j < 32; ++j) {
+            expected[i*32 + j] = ((uint32_t)dataIn[i*2*64 + j*2] + dataIn[i*2*64 + j*2 + 1] +
+                                  dataIn[i*2*64 + j*2 + 64] + dataIn[i*2*64 + j*2 + 64+1]) / 4;
+        }
+    }
+    EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates one 2D Allocations, one with 128 * 128 Float Elements with
+ * allocationCubeCreateFromBitmap. The Allocation is pre-populated with dataIn
+ * and the mipmaps are filled with allocationGenerateMipmaps. Then dataOut is
+ * then overridden with allocation2DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCubeCreateFromBitmap,
+ * allocation2DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, SimpleCubemapTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 128 x 128 x float1
+    Type type = context->typeCreate(element, 128, 128, 0, false, true, YuvFormat::YUV_NONE);
+    std::vector<float> dataIn(128*128*6), dataOut(128*128), expected(128*128);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+    // 128 x 128 x float1 x 6
+    Allocation allocation = context->allocationCubeCreateFromBitmap(
+        type, AllocationMipmapControl::NONE, _data, (int)AllocationUsageType::SCRIPT);
+    EXPECT_NE(Allocation(0), allocation);
+
+    context->allocation2DRead(allocation, 0, 0, 0, AllocationCubemapFace::NEGATIVE_Z, 128,
+                              128, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float),
+                              128*sizeof(float));
+    for (int i = 0; i < 128; ++i) {
+        for (int j = 0; j < 128; ++j) {
+            expected[i*128 + j] = i*128*6 + j + 128*5;
+        }
+    }
+    EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates a complex element type (uint8_t, uint32_t) out of known
+ * elements. It then verifies the element structure was created correctly.
+ * Finally, the test creates a 128-wide, 1-dimension allocation of this type
+ * and transfers memory to and from this structure.
+ *
+ * Calls: elementCreate, elementComplexCreate, elementGetSubElements,
+ * typeCreate, allocationCreateTyped, allocationElementWrite,
+ * allocationElementRead
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ComplexElementTest) {
+    Element element1 = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+    Element element2 = context->elementCreate(DataType::UNSIGNED_32, DataKind::USER, false, 1);
+
+    hidl_vec<Element> eins = {element1, element2};
+    hidl_vec<hidl_string> names = {hidl_string("first"), hidl_string("second")};
+    hidl_vec<Size> arraySizesPtr = {sizeof(uint8_t), sizeof(uint32_t)};
+    Element element3 = context->elementComplexCreate(eins, names, arraySizesPtr);
+    EXPECT_NE(Element(0), element3);
+
+    std::vector<Element> ids;
+    std::vector<std::string> namesOut;
+    std::vector<Size> arraySizesOut;
+    context->elementGetSubElements(element3, 2, [&](const hidl_vec<Element>& _ids,
+                                                    const hidl_vec<hidl_string>& _names,
+                                                    const hidl_vec<Size>& _arraySizes){
+                                                        ids = _ids;
+                                                        namesOut.push_back(_names[0]);
+                                                        namesOut.push_back(_names[1]);
+                                                        arraySizesOut = _arraySizes;
+                                                    });
+    EXPECT_NE(Element(0), ids[0]);
+    EXPECT_NE(Element(0), ids[1]);
+    EXPECT_EQ("first", namesOut[0]);
+    EXPECT_EQ("second", namesOut[1]);
+    EXPECT_EQ(sizeof(uint8_t), arraySizesOut[0]);
+    EXPECT_EQ(sizeof(uint32_t), arraySizesOut[1]);
+
+    // 128 x (uint8_t, uint32_t)
+    Type type = context->typeCreate(element3, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+    // 128 x (uint8_t, uint32_t)
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    std::vector<uint32_t> dataIn(128), dataOut(128);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static uint32_t val = 0; return val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(uint32_t));
+    context->allocationElementWrite(allocation, 0, 0, 0, 0, _data, 1);
+    context->allocationElementRead(allocation, 0, 0, 0, 0, (Ptr)dataOut.data(),
+                                   (Size)dataOut.size()*sizeof(uint32_t), 1);
+    bool same = std::all_of(dataOut.begin(), dataOut.end(),
+                            [](uint32_t x){ static uint32_t val = 0; return x == val++; });
+    EXPECT_EQ(true, same);
+}
+*/
diff --git a/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp
new file mode 100644
index 0000000..f505d01
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "VtsHalRenderscriptV1_0TargetTest.h"
+
+// The main test class for RENDERSCRIPT HIDL HAL.
+void RenderscriptHidlTest::SetUp() {
+    device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>();
+    ASSERT_NE(nullptr, device.get());
+
+    uint32_t version = 0;
+    uint32_t flags = 0;
+    context = device->contextCreate(version, ContextType::NORMAL, flags);
+    ASSERT_NE(nullptr, context.get());
+}
+
+void RenderscriptHidlTest::TearDown() {
+    context->contextDestroy();
+}
+
+// A class for test environment setup (kept since this file is a template).
+class RenderscriptHidlEnvironment : public ::testing::Environment {
+public:
+    virtual void SetUp() {}
+    virtual void TearDown() {}
+};
+
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(new RenderscriptHidlEnvironment);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
diff --git a/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h
new file mode 100644
index 0000000..fc1b7e4
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VTS_HAL_RENDERSCRIPT_V1_0_TARGET_TESTS_H
+#define VTS_HAL_RENDERSCRIPT_V1_0_TARGET_TESTS_H
+
+#define LOG_TAG "renderscript_hidl_hal_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/renderscript/1.0/IContext.h>
+#include <android/hardware/renderscript/1.0/IDevice.h>
+#include <android/hardware/renderscript/1.0/types.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+
+using ::android::hardware::renderscript::V1_0::Allocation;
+using ::android::hardware::renderscript::V1_0::AllocationAdapter;
+using ::android::hardware::renderscript::V1_0::AllocationCubemapFace;
+using ::android::hardware::renderscript::V1_0::AllocationMipmapControl;
+using ::android::hardware::renderscript::V1_0::AllocationUsageType;
+using ::android::hardware::renderscript::V1_0::IContext;
+using ::android::hardware::renderscript::V1_0::IDevice;
+using ::android::hardware::renderscript::V1_0::ContextType;
+using ::android::hardware::renderscript::V1_0::DataType;
+using ::android::hardware::renderscript::V1_0::DataKind;
+using ::android::hardware::renderscript::V1_0::Element;
+using ::android::hardware::renderscript::V1_0::MessageToClientType;
+using ::android::hardware::renderscript::V1_0::NativeWindow;
+using ::android::hardware::renderscript::V1_0::ObjectBase;
+using ::android::hardware::renderscript::V1_0::OpaqueHandle;
+using ::android::hardware::renderscript::V1_0::Ptr;
+using ::android::hardware::renderscript::V1_0::Sampler;
+using ::android::hardware::renderscript::V1_0::SamplerValue;
+using ::android::hardware::renderscript::V1_0::Script;
+using ::android::hardware::renderscript::V1_0::ScriptFieldID;
+using ::android::hardware::renderscript::V1_0::ScriptGroup;
+using ::android::hardware::renderscript::V1_0::ScriptGroup2;
+using ::android::hardware::renderscript::V1_0::ScriptIntrinsicID;
+using ::android::hardware::renderscript::V1_0::ScriptInvokeID;
+using ::android::hardware::renderscript::V1_0::ScriptKernelID;
+using ::android::hardware::renderscript::V1_0::Size;
+using ::android::hardware::renderscript::V1_0::ThreadPriorities;
+using ::android::hardware::renderscript::V1_0::Type;
+using ::android::hardware::renderscript::V1_0::YuvFormat;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+// bitcode variables
+typedef signed char int8_t;
+extern const int8_t bitCode[];
+extern const int bitCodeLength;
+
+// The main test class for RENDERSCRIPT HIDL HAL.
+class RenderscriptHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+public:
+    virtual void SetUp() override;
+    virtual void TearDown() override;
+
+    sp<IContext>   context;
+
+private:
+    sp<IDevice>    device;
+};
+
+#endif // VTS_HAL_RENDERSCRIPT_V1_0_TARGET_TESTS_H
diff --git a/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp b/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
new file mode 100644
index 0000000..c2b3354
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
@@ -0,0 +1,278 @@
+/*
+ * 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 "VtsHalRenderscriptV1_0TargetTest.h"
+
+/*
+ * ContextCreateAndDestroy:
+ * Creates a RenderScript context and immediately destroys the context.
+ * Since create and destroy calls are a part of SetUp() and TearDown(),
+ * the test definition is intentionally kept empty
+ *
+ * Calls: getService<IDevice>, contextCreate, contextDestroy
+ */
+TEST_F(RenderscriptHidlTest, ContextCreateAndDestroy) {}
+
+/*
+ * Create an Element and verify the return value is valid.
+ *
+ * Calls: elementCreate
+ */
+TEST_F(RenderscriptHidlTest, ElementCreate) {
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    EXPECT_NE(Element(0), element);
+}
+
+/*
+ * Create an Element, a Type and an Allocation of that type, and verify the
+ * return values are valid.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocationGetType
+ */
+TEST_F(RenderscriptHidlTest, ElementTypeAllocationCreate) {
+    // Element create test
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    EXPECT_NE(Element(0), element);
+
+    // Type create test
+    Type type = context->typeCreate(element, 1, 0, 0, false, false, YuvFormat::YUV_NONE);
+    EXPECT_NE(Type(0), type);
+
+    // Allocation create test
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                           (int)((uint32_t)AllocationUsageType::ALL
+                                                           & ~(uint32_t)AllocationUsageType::OEM),
+                                                           (Ptr)nullptr);
+    EXPECT_NE(Allocation(0), allocation);
+
+    // Allocation type test
+    Type type2 = context->allocationGetType(allocation);
+    EXPECT_EQ(type, type2);
+}
+
+/*
+ * Create an Element, a Type of the Element, and verify the native metadata can
+ * be retrieved correctly.
+ *
+ * Calls: elementCreate, typeCreate, elementGetNativeMetadata,
+ * typeGetNativeMetadata
+ */
+TEST_F(RenderscriptHidlTest, MetadataTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 128 x float1
+    Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+
+    std::vector<uint32_t> elementMetadata(5);
+    context->elementGetNativeMetadata(element, [&](const hidl_vec<uint32_t>& _metadata){
+                                          elementMetadata = _metadata; });
+    EXPECT_EQ(DataType::FLOAT_32, (DataType)elementMetadata[0]);
+    EXPECT_EQ(DataKind::USER, (DataKind)elementMetadata[1]);
+    EXPECT_EQ(false, ((uint32_t)elementMetadata[2] == 1) ? true : false);
+    EXPECT_EQ(1u, (uint32_t)elementMetadata[3]);
+    EXPECT_EQ(0u, (uint32_t)elementMetadata[4]);
+
+    std::vector<OpaqueHandle> typeMetadata(6);
+    context->typeGetNativeMetadata(type, [&typeMetadata](const hidl_vec<OpaqueHandle>& _metadata){
+                                   typeMetadata = _metadata; });
+    EXPECT_EQ(128u, (uint32_t)typeMetadata[0]);
+    EXPECT_EQ(0u, (uint32_t)typeMetadata[1]);
+    EXPECT_EQ(0u, (uint32_t)typeMetadata[2]);
+    EXPECT_NE(true, typeMetadata[3]);
+    EXPECT_NE(true, typeMetadata[4]);
+    EXPECT_EQ(element, (Element)typeMetadata[5]);
+}
+
+/*
+ * Create a Allocation, and verified allocationGetPointer and allocationResize1D
+ * return valid values.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped,
+ * allocationGetPointer, allocationResize1D
+ */
+TEST_F(RenderscriptHidlTest, ResizeTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 128 x float1
+    Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+    // 128 x float1
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    Ptr dataPtr1, dataPtr2;
+    Size stride;
+    context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
+                                  [&](Ptr _dataPtr, Size _stride){
+                                      dataPtr1 = _dataPtr; stride = _stride; });
+    EXPECT_EQ(0ul, stride);
+
+    context->allocationResize1D(allocation, 1024*1024);
+    context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
+                                  [&](Ptr _dataPtr, Size _stride){
+                                      dataPtr2 = _dataPtr; stride = _stride; });
+    EXPECT_EQ(0ul, stride);
+    EXPECT_NE(dataPtr1, dataPtr2);
+}
+
+/*
+ * Test creates two allocations, one with IO_INPUT and one with IO_OUTPUT. The
+ * NativeWindow (Surface) is retrieved from one allocation and set to the other.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
+ * allocationGetNativeWindow, allocationSetNativeWindow, allocationIoSend,
+ * allocationIoReceive, allocation2DRead
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, NativeWindowIoTest) {
+    // uint8x4
+    Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 4);
+    // 512 x 512 x uint8x4
+    Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+    std::vector<uint32_t> dataIn(512*512), dataOut(512*512);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (uint32_t)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(uint32_t));
+    // 512 x 512 x float1
+    Allocation allocationRecv = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                               (int)(AllocationUsageType::SCRIPT
+                                                               | AllocationUsageType::IO_INPUT),
+                                                               (Ptr)nullptr);
+    Allocation allocationSend = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                               (int)(AllocationUsageType::SCRIPT
+                                                               | AllocationUsageType::IO_OUTPUT),
+                                                               (Ptr)nullptr);
+    context->allocation2DWrite(allocationSend, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
+                               _data, 0);
+    NativeWindow nativeWindow = context->allocationGetNativeWindow(allocationRecv);
+    EXPECT_NE(NativeWindow(0), nativeWindow);
+
+    context->allocationSetNativeWindow(allocationSend, nativeWindow);
+    context->allocationIoSend(allocationSend);
+    context->allocationIoReceive(allocationRecv);
+    context->allocation2DRead(allocationRecv, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
+                              (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint32_t), 0);
+    bool same = std::all_of(dataOut.begin(), dataOut.end(),
+                             [](uint32_t x){ static int val = 0; return x == (uint32_t)val++; });
+    EXPECT_EQ(true, same);
+}
+*/
+
+/*
+ * Three allocations are created, two with IO_INPUT and one with IO_OUTPUT. The
+ * two allocations with IO_INPUT are made to share the same BufferQueue.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped,
+ * allocationCreateFromBitmap, allocationSetupBufferQueue,
+ * allocationShareBufferQueue
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, BufferQueueTest) {
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 512 x 512 x float1
+    Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+    std::vector<float> dataIn(512*512), dataOut1(512*512), dataOut2(512*512);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+    // 512 x 512 x float1
+    Allocation allocationRecv1 = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                                (int)(AllocationUsageType::SCRIPT
+                                                                | AllocationUsageType::IO_INPUT),
+                                                                (Ptr)nullptr);
+    Allocation allocationRecv2 = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                                (int)(AllocationUsageType::SCRIPT
+                                                                | AllocationUsageType::IO_INPUT),
+                                                                (Ptr)nullptr);
+    Allocation allocationSend = context->allocationCreateFromBitmap(type,
+                                                                    AllocationMipmapControl::NONE,
+                                                                    _data,
+                                                                   (int)(AllocationUsageType::SCRIPT
+                                                                 | AllocationUsageType::IO_OUTPUT));
+    context->allocationSetupBufferQueue(allocationRecv1, 2);
+    context->allocationShareBufferQueue(allocationRecv1, allocationRecv2);
+    // TODO: test the buffer queue
+}
+*/
+
+/*
+ * This test sets up the message queue, sends a message, peeks at the message,
+ * and reads it back.
+ *
+ * Calls: contextInitToClient, contextSendMessage, contextPeekMessage,
+ * contextGetMessage, contextDeinitToClient, contextLog
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ContextMessageTest) {
+    context->contextInitToClient();
+
+    std::string messageOut = "correct";
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)const_cast<char*>(messageOut.c_str()), messageOut.length());
+    context->contextSendMessage(0, _data);
+    MessageToClientType messageType;
+    size_t size;
+    uint32_t subID;
+    context->contextPeekMessage([&](MessageToClientType _type, Size _size, uint32_t _subID){
+                                messageType = _type; size = (uint32_t)_size; subID = _subID; });
+    std::vector<char> messageIn(size, '\0');
+    context->contextGetMessage(messageIn.data(), messageIn.size(),
+                               [&](MessageToClientType _type, Size _size){
+                               messageType = _type; size = (uint32_t)_size; });
+    EXPECT_EQ(messageOut, messageIn.data());
+
+    context->contextDeinitToClient();
+    context->contextLog();
+}
+*/
+
+/*
+ * Call through a bunch of APIs and make sure they don’t crash. Assign the name
+ * of a object and check getName returns the name just set.
+ *
+ * Calls: contextSetPriority, contextSetCacheDir, elementCreate, assignName,
+ * contextFinish, getName, objDestroy, samplerCreate
+ */
+TEST_F(RenderscriptHidlTest, MiscellaneousTests) {
+    context->contextSetPriority(ThreadPriorities::NORMAL);
+    context->contextSetCacheDir("/data/local/tmp/temp/");
+
+    Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+    std::string nameIn = "element_test_name";
+    std::string nameOut = "not_name";
+    hidl_string _nameIn;
+    _nameIn.setToExternal(nameIn.c_str(), nameIn.length());
+    context->assignName(element, _nameIn);
+    context->contextFinish();
+    context->getName(element, [&](const hidl_string& _name){ nameOut = _name.c_str(); });
+    EXPECT_EQ("element_test_name", nameOut);
+
+    context->objDestroy(element);
+
+    Sampler sampler = context->samplerCreate(SamplerValue::LINEAR, SamplerValue::LINEAR,
+                                             SamplerValue::LINEAR, SamplerValue::LINEAR,
+                                             SamplerValue::LINEAR, 8.0f);
+    EXPECT_NE(Sampler(0), sampler);
+}
diff --git a/renderscript/1.0/vts/functional/VtsScriptTests.cpp b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
new file mode 100644
index 0000000..9531e19
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
@@ -0,0 +1,390 @@
+/*
+ * 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 "VtsHalRenderscriptV1_0TargetTest.h"
+
+/*
+ * Create a Blur intrinsic with scriptIntrinsicCreate, and call
+ * scriptSetTimeZone to make sure it is not crashing.
+ *
+ * Calls: elementCreate, scriptIntrinsicCreate, scriptSetTimeZone
+ */
+TEST_F(RenderscriptHidlTest, IntrinsicTest) {
+    // uint8
+    Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+    Script script = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLUR, element);
+    EXPECT_NE(Script(0), script);
+
+    context->scriptSetTimeZone(script, "UTF-8");
+}
+
+/*
+ * Create a user script “struct_test”, and verified the setters and getters work
+ * for the global variables.
+ *
+ * Calls: scriptCCreate, scriptGetVarV, scriptSetVarI, scriptSetVarJ,
+ * scriptSetVarF, scriptSetVarD, elementCreate, typeCreate,
+ * allocationCreateTyped, scriptSetVarObj, scriptSetVarV, scriptSetVarVE
+ */
+TEST_F(RenderscriptHidlTest, ScriptVarTest) {
+    hidl_vec<uint8_t> bitcode;
+    bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+    Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+    EXPECT_NE(Script(0), script);
+
+    // arg tests
+    context->scriptSetVarI(script, 0, 100);
+    int resultI = 0;
+    context->scriptGetVarV(script, 0, sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+                               resultI = *((int*)_data.data()); });
+    EXPECT_EQ(100, resultI);
+
+    context->scriptSetVarJ(script, 1, 101l);
+    int resultJ = 0;
+    context->scriptGetVarV(script, 1, sizeof(long), [&](const hidl_vec<uint8_t>& _data){
+                               resultJ = *((long*)_data.data()); });
+    EXPECT_EQ(101, resultJ);
+
+    context->scriptSetVarF(script, 2, 102.0f);
+    int resultF = 0.0f;
+    context->scriptGetVarV(script, 2, sizeof(float), [&](const hidl_vec<uint8_t>& _data){
+                               resultF = *((float*)_data.data()); });
+    EXPECT_EQ(102.0f, resultF);
+
+    context->scriptSetVarD(script, 3, 103.0);
+    int resultD = 0.0;
+    context->scriptGetVarV(script, 3, sizeof(double), [&](const hidl_vec<uint8_t>& _data){
+                               resultD = *((double*)_data.data()); });
+    EXPECT_EQ(103.0, resultD);
+
+    // float1
+    Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+    // 128 x float1
+    Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+    // 128 x float1
+    Allocation allocationIn = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                             (int)AllocationUsageType::SCRIPT,
+                                                             (Ptr)nullptr);
+    Allocation allocationOut = Allocation(0);
+    context->scriptSetVarObj(script, 4, (ObjectBase)allocationIn);
+    context->scriptGetVarV(script, 4, sizeof(ObjectBase), [&](const hidl_vec<uint8_t>& _data){
+                               allocationOut = (Allocation) *((ObjectBase*)_data.data()); });
+    EXPECT_EQ(allocationOut, allocationIn);
+
+    std::vector<int> arrayIn = {500, 501, 502, 503};
+    std::vector<int> arrayOut(4);
+    hidl_vec<uint8_t> arrayData;
+    arrayData.setToExternal((uint8_t*)arrayIn.data(), arrayIn.size()*sizeof(int));
+    context->scriptSetVarV(script, 5, arrayData);
+    context->scriptGetVarV(script, 5, 4*sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+                               arrayOut = std::vector<int>((int*)_data.data(),
+                                                           (int*)_data.data() + 4); });
+    EXPECT_EQ(500, arrayOut[0]);
+    EXPECT_EQ(501, arrayOut[1]);
+    EXPECT_EQ(502, arrayOut[2]);
+    EXPECT_EQ(503, arrayOut[3]);
+
+    std::vector<int> dataVE = {1000, 1001};
+    std::vector<uint32_t> dimsVE = {1};
+    std::vector<int> outVE(2);
+    hidl_vec<uint8_t> _dataVE;
+    hidl_vec<uint32_t> _dimsVE;
+    _dataVE.setToExternal((uint8_t*)dataVE.data(), dataVE.size()*sizeof(int));
+    _dimsVE.setToExternal((uint32_t*)dimsVE.data(), dimsVE.size());
+    // intx2
+    Element elementVE = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 2);
+    context->scriptSetVarVE(script, 6, _dataVE, elementVE, _dimsVE);
+    context->scriptGetVarV(script, 6, 2*sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+                               outVE = std::vector<int>((int*)_data.data(),
+                                                        (int*)_data.data() + 2); });
+    EXPECT_EQ(1000, outVE[0]);
+    EXPECT_EQ(1001, outVE[1]);
+}
+
+/*
+ * Create a user script “struct_test”, and input and output Allocations.
+ * Verified the foreach launch correctly for the invoke kernel.
+ *
+ * Calls: scriptCCreate, scriptInvoke, scriptGetVarV, scriptInvokeV
+ */
+TEST_F(RenderscriptHidlTest, ScriptInvokeTest) {
+    hidl_vec<uint8_t> bitcode;
+    bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+    Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+    EXPECT_NE(Script(0), script);
+
+    // invoke test
+    int function_res = 0;
+    context->scriptInvoke(script, 0);
+    context->scriptGetVarV(script, 0, sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+                               function_res = *((int*)_data.data()); });
+    EXPECT_NE(100, function_res);
+
+    // invokeV test
+    int functionV_arg = 5;
+    int functionV_res = 0;
+    hidl_vec<uint8_t> functionV_data;
+    functionV_data.setToExternal((uint8_t*)&functionV_arg, sizeof(int));
+    context->scriptInvokeV(script, 1, functionV_data);
+    context->scriptGetVarV(script, 0, sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+                               functionV_res = *((int*)_data.data()); });
+    EXPECT_EQ(5, functionV_res);
+}
+
+/*
+ * Create a user script “struct_test”, and input and output Allocations.
+ * Verified the foreach launch correctly for the foreach kernel.
+ *
+ * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
+ * allocation1DWrite, scriptForEach, allocationRead
+ */
+TEST_F(RenderscriptHidlTest, ScriptForEachTest) {
+    hidl_vec<uint8_t> bitcode;
+    bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+    Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+    EXPECT_NE(Script(0), script);
+
+    // uint8_t
+    Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+    // 64 x uint8_t
+    Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
+    std::vector<uint8_t> dataIn(64), dataOut(64);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static uint8_t val = 0; return val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size());
+    // 64 x float1
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    Allocation vout = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                     (int)AllocationUsageType::SCRIPT,
+                                                     (Ptr)nullptr);
+    context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
+    hidl_vec<Allocation> vains;
+    vains.setToExternal(&allocation, 1);
+    hidl_vec<uint8_t> params;
+    context->scriptForEach(script, 1, vains, vout, params, nullptr);
+    context->allocationRead(vout, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint8_t));
+    bool same = std::all_of(dataOut.begin(), dataOut.end(),
+                            [](uint8_t x){ static uint8_t val = 1; return x == val++; });
+    EXPECT_EQ(true, same);
+}
+
+/*
+ * Create a user script “struct_test”, and input and output Allocations.
+ * Verified the foreach launch correctly for the reduction kernel.
+ *
+ * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
+ * allocation1DWrite, scriptReduce, contextFinish, allocationRead
+ */
+TEST_F(RenderscriptHidlTest, ScriptReduceTest) {
+    hidl_vec<uint8_t> bitcode;
+    bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+    Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+    EXPECT_NE(Script(0), script);
+
+    // uint8_t
+    Element element = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 1);
+    // 64 x uint8_t
+    Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
+    Type type2 = context->typeCreate(element, 1, 0, 0, false, false, YuvFormat::YUV_NONE);
+    std::vector<int> dataIn(64), dataOut(1);
+    std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return val++; });
+    hidl_vec<uint8_t> _data;
+    _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(int));
+    // 64 x float1
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    Allocation vaout = context->allocationCreateTyped(type2, AllocationMipmapControl::NONE,
+                                                      (int)AllocationUsageType::SCRIPT,
+                                                      (Ptr)nullptr);
+    context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
+    hidl_vec<Allocation> vains;
+    vains.setToExternal(&allocation, 1);
+    context->scriptReduce(script, 0, vains, vaout, nullptr);
+    context->contextFinish();
+    context->allocationRead(vaout, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(int));
+    // sum of 0, 1, 2, ..., 62, 63
+    int sum = 63*64/2;
+    EXPECT_EQ(sum, dataOut[0]);
+}
+
+/*
+ * This test creates an allocation and binds it to a data segment in the
+ * RenderScript script, represented in the bitcode.
+ *
+ * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
+ * allocationGetPointer, scriptBindAllocation
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ScriptBindTest) {
+    hidl_vec<uint8_t> bitcode;
+    bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+    Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+    EXPECT_NE(Script(0), script);
+
+    // uint8_t
+    Element element = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 1);
+    // 64 x uint8_t
+    Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
+    // 64 x float1
+    Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    Ptr dataPtr1, dataPtr2;
+    Size stride;
+    context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
+                                  [&](Ptr _dataPtr, Size _stride){ dataPtr1 = _dataPtr;
+                                      stride = _stride; });
+    context->scriptBindAllocation(script, allocation, 7);
+    context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
+                                  [&](Ptr _dataPtr, Size _stride){ dataPtr2 = _dataPtr;
+                                      stride = _stride; });
+    EXPECT_NE(dataPtr1, dataPtr2);
+}
+*/
+
+/*
+ * This test groups together two RenderScript intrinsic kernels to run one after
+ * the other asynchronously with respect to the client. The test configures YuvToRGB(A) and Blur,
+ * and links them together such that Blur will execute after YuvToRGB(A) and use its result. The
+ * test checks the data returned to make sure it was changed after passing through the entire
+ * ScriptGroup.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
+ * scriptIntrinsicCreate, scriptKernelIDCreate, scriptGroupCreate,
+ * scriptGroupSetInput, scriptGroupSetOutput, scriptGroupExecute,
+ * allocation2DRead
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ScriptGroupTest) {
+    //std::vector<uint8_t> dataIn(256*256*1, 128), dataOut(256*256*3, 0);
+    std::vector<uint8_t> dataIn(256*256*1, 128), dataOut(256*256*4, 0);
+    hidl_vec<uint8_t> _dataIn, _dataOut;
+    _dataIn.setToExternal(dataIn.data(), dataIn.size());
+    _dataOut.setToExternal(dataOut.data(), dataIn.size());
+
+    // 256 x 256 YUV pixels
+    Element element1 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_YUV, true, 1);
+    //Type type1 = context->typeCreate(element1, 256, 256, 0, false, false, YuvFormat::YUV_420_888);
+    Type type1 = context->typeCreate(element1, 256, 256, 0, false, false, YuvFormat::YUV_NV21);
+    Allocation allocation1 = context->allocationCreateTyped(type1, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    context->allocation2DWrite(allocation1, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
+                               _dataIn, 0);
+    Script yuv2rgb = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_YUV_TO_RGB, element1);
+    EXPECT_NE(Script(0), yuv2rgb);
+
+    ScriptKernelID yuv2rgbKID = context->scriptKernelIDCreate(yuv2rgb, 0, 2);
+    EXPECT_NE(ScriptKernelID(0), yuv2rgbKID);
+
+    // 256 x 256 RGB pixels
+    //Element element2 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_RGB, true, 3);
+    Element element2 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_RGBA, true, 4);
+    Type type2 = context->typeCreate(element2, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
+    Allocation allocation2 = context->allocationCreateTyped(type2, AllocationMipmapControl::NONE,
+                                                           (int)AllocationUsageType::SCRIPT,
+                                                           (Ptr)nullptr);
+    context->allocation2DWrite(allocation2, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
+                               _dataOut, 0);
+    Script blur = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLUR, element2);
+    EXPECT_NE(Script(0), blur);
+
+    ScriptKernelID blurKID = context->scriptKernelIDCreate(blur, 0, 2);
+    EXPECT_NE(ScriptKernelID(0), blurKID);
+
+    // ScriptGroup
+    hidl_vec<ScriptKernelID> kernels = {yuv2rgbKID, blurKID};
+    hidl_vec<ScriptKernelID> srcK = {yuv2rgbKID};
+    hidl_vec<ScriptKernelID> dstK = {blurKID};
+    hidl_vec<ScriptFieldID> dstF = {};
+    hidl_vec<Type> types = {type2};
+    ScriptGroup scriptGroup = context->scriptGroupCreate(kernels, srcK, dstK, dstF, types);
+    EXPECT_NE(ScriptGroup(0), scriptGroup);
+
+    context->scriptGroupSetInput(scriptGroup, yuv2rgbKID, allocation1);
+    context->scriptGroupSetOutput(scriptGroup, blurKID, allocation2);
+    context->scriptGroupExecute(scriptGroup);
+
+    // verify contents were changed
+    context->allocation2DRead(allocation2, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
+                              (Ptr)dataOut.data(), (Size)dataOut.size(), 0);
+    bool same = std::all_of(dataOut.begin(), dataOut.end(), [](uint8_t x){ return x != 0; });
+    EXPECT_EQ(true, same);
+}
+*/
+
+/*
+ * Similar to the ScriptGroup test, this test verifies the execution flow of
+ * RenderScript kernels and invokables.
+ *
+ * Calls: scriptFieldIDCreate, closureCreate, scriptInvokeIDCreate,
+ * invokeClosureCreate, closureSetArg, closureSetGlobal, scriptGroup2Create,
+ * scriptGroupExecute
+ *
+ * This test currently still a work in progress, and should be finished by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ScriptGroup2Test) {
+
+    ScriptFieldID fieldID = context->scriptFieldIDCreate(script, slot);
+    EXPECT_NE(ScriptFieldID(0), fieldID);
+
+    ScriptKernelID kernelID = context->scriptKernelIDCreate(script, slot, sig);
+    EXPECT_NE(ScriptKernelID(0), kernelID);
+
+    Allocation returnValue = 0;
+    hidl_vec<ScriptFieldID> fieldIDS = {};
+    hidl_vec<int64_t> values = {};
+    hidl_vec<int32_t> sizes = {};
+    hidl_veC<Closure> depClosures = {};
+    hidl_vec<ScriptFieldID> depFieldIDS = {};
+    Closure closure1 = context->closureCreate(kernelID, returnValue, fieldIDS, values, sizes,
+                                             depClosures, depFieldIDS);
+    EXPECT_NE(Closure(0), closure1);
+
+    ScriptInvokeID invokeID = context->scriptInvokeIDCreate(script, slot);
+    EXPECT_NE(ScriptInvokeID(0), invokeID);
+
+    hidl_vec<uint8_t> params = {};
+    hidl_vec<ScriptFieldID> fieldsIDS2 = {};
+    hidl_vec<int64_t> values2 = {};
+    hidl_vec<int32_t> sizes2 = {};
+    Closure closure2 = context->invokeClosureCreate(invokeID, params, fieldIDS2, values2, sizes2);
+    EXPECT_NE(Closure(0), closure2);
+
+    context->closureSetArg(closure, index, value, size);
+    context->closureSetGlobal(closure, fieldID, value, size);
+
+    hidl_string name = "script_group_2_test";
+    hidl_string cacheDir = "data/local/tmp/";
+    hidl_vec<Closures> closures;
+    ScriptGroup2 scriptGroup2 = context->scriptGroup2Create(name, cacheDir, closures);
+    EXPECT_NE(ScriptGroup2(0), scriptGroup2);
+
+    context->scriptGroupExecute(scriptGroup2);
+    // verify script group launched...
+}
+*/
diff --git a/renderscript/1.0/vts/functional/bitcode.cpp b/renderscript/1.0/vts/functional/bitcode.cpp
new file mode 100644
index 0000000..72143c9
--- /dev/null
+++ b/renderscript/1.0/vts/functional/bitcode.cpp
@@ -0,0 +1,436 @@
+/*
+ * 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 "shared.rsh"
+
+// types
+typedef struct Point2 {
+    int x;
+    int y;
+} Point_2;
+
+// variables
+int var_int;
+long var_long;
+float var_float;
+double var_double;
+rs_allocation var_allocation;
+int var_array[4];
+Point_2 var_point2;
+Point_2 *var_point2_ptr;
+
+// invoke
+void function() {
+    var_int = 1;
+    var_long = 2;
+    var_float = 3.0f;
+    var_double = 4.0;
+
+    var_array[0] = 5;
+    var_array[1] = 6;
+    var_array[2] = 7;
+    var_array[3] = 8;
+
+    var_point2.x = 9;
+    var_point2.y = 10;
+}
+
+// invokeV
+void functionV(int arg) {
+    var_int = arg;
+}
+
+// forEach
+uchar RS_KERNEL increment(uchar in) {
+    return in+1;
+}
+
+// reduction
+#pragma rs reduce(summation) accumulator(sumAccumulator) combiner(sumCombiner)
+
+static void sumAccumulator(int* accum, int val) {
+    *accum += val;
+}
+
+static void sumCombiner(int* accum, const int *val) {
+    *accum += *val;
+}
+*/
+
+#include "VtsHalRenderscriptV1_0TargetTest.h"
+
+#ifndef __LP64__
+
+const int8_t bitCode[] = {
+     -34,  -64,   23,   11,    0,    0,    0,    0,   44,    0,    0,    0,  -84,   10,    0,    0,
+       0,    0,    0,    0,   -1,   -1,   -1,   -1,    0,    0,    0,    0,    1,   64,    4,    0,
+      96,    9,    0,    0,    2,   64,    4,    0,    3,    0,    0,    0,   66,   67,  -64,  -34,
+      33,   12,    0,    0,  -88,    2,    0,    0,    1,   16,    0,    0,   18,    0,    0,    0,
+       7, -127,   35, -111,   65,  -56,    4,   73,    6,   16,   50,   57, -110,    1, -124,   12,
+      37,    5,    8,   25,   30,    4, -117,   98, -128,   24,   69,    2,   66, -110,   11,   66,
+     -60,   16,   50,   20,   56,    8,   24,   73,   10,   50,   68,   36,   72,   10, -112,   33,
+      35,  -60,   82, -128,   12,   25,   33,  114,   36,    7,  -56, -120,   17,   98,  -88,  -96,
+     -88,   64,  -58,  -16,    1,    0,    0,    0,   73,   24,    0,    0,   25,    0,    0,    0,
+      11, -124,   -1,   -1,   -1,   -1,   31,  -64,   96, -127,    1,    4,   65,  -16,   -1,   -1,
+      -1,   -1,    3,   24,   45,   32,    2,   16,    4,   65,   16,   36,   -2,   -1,   -1,   -1,
+     127,    0, -125,    5,   70,    0, -126,   32,    8, -126, -124,    0, -126,   32,    8, -126,
+     -60,   -1,   -1,   -1,   -1,   15,   96,  -80,   64,   -8,   -1,   -1,   -1,   -1,    1,   12,
+      22,    8,   -1,   -1,   -1,   -1,   63,    0,   11, -120,    0,    4,   65,   16,    4, -119,
+      -1,   -1,   -1,   -1,   31,  -64,   80,   88,   64,    4,  -64,   -1,   -1,   -1,   -1,   15,
+      96,    0,    0,    0, -119,   32,    0,    0,   33,    0,    0,    0,   50,   34, -120,    9,
+      32,  100, -123,    4,   19,   35,  -92, -124,    4,   19,   35,  -29, -124,  -95, -112,   20,
+      18,   76, -116, -116,   11, -124,  -60,   76,   16, -112,  -63,   28,    1,   24,   16,   48,
+      71,    0,   10,   36,  -52,    0,   16,   49,    4,   64,   70,   18,    0, -124,   92,   35,
+      77,   17,   37,   76,  126,  -22,   32,  -51,  100,   35,    1,    0,   72,  -71,   75, -102,
+      34,   74, -104,   -4,   72,   -6, -127,  101,  113,    4,   96,   66, -100,  -58,  -65,  115,
+      20,    4,  -60,  -48,   50,   71, -128,  -48,   67,  -48,    8,   64,    9,   36, -102, -118,
+      32,    1,   84,   21,  -31,  121,  -24,   42, -125,   20,    0, -108, -107,   65,   10,    2,
+     -38, -118,   32,   53,  -44, -103,    0,  -96,  -81,    8,   18,   72,  -31,   64,    0,    0,
+      19,  -80,  112, -112, -121,  118,  -80, -121,   59,  104,    3,  119,  120,    7,  119,   40,
+    -121,   54,   96, -121,  116,  112, -121,  122,  -64, -121,   54,   56,    7,  119,  -88, -121,
+     114,    8,    7,  113,   72, -121,   13,  100,   80,   14,  109,    0,   15,  122,   48,    7,
+     114,  -96,    7,  115,   32,    7,  109, -112,   14,  118,   64,    7,  122,   96,    7,  116,
+     -48,    6,  -10,   16,    7,  114, -128,    7,  122,   96,    7,  116,  -96,    7,  113,   32,
+       7,  120,  -48,    6,  -18,   48,    7,  114,  -48,    6,  -77,   96,    7,  116,  -96,  -13,
+      64, -118,    4,   50,   66,  100,    4,  -40,  -95,    4,  -64, -124,   12,    0,    0,    4,
+     -64,   14,  101,    0,   44, -124,    0,    0,   32,    0,  118,   40,    5,  112,   33,    3,
+       0,    0,    1,  -80,   67,   57,    0,   12,   33,    0,    0,    8, -128,   29,   74,    2,
+     100,  -56,    0,    0,   64,    0,  -20,   80,   22,   64,   67,    6,    0,    0,    2, -128,
+      13, -121,  -37,  -95,   56,  -64, -122,   12,    0,    0,    4,  -64,   14,   37,    2,   58,
+      96,    0,    0,   32,    0,  118,   40,   17,  -32,    1,    3,    0,    0,    1,   48,   68,
+     -95,    0,    0,    8,    0,    0,    0, -126,   33, -118,    5,    0,   64,    0,    0,    0,
+      16,   12,   81,   48,    0,    0,    4,    0,    0, -128,   96, -120,  -94,    1,  -64,   48,
+       0,    0,    0,    0,   67,   20,   14,    0,    6,    2,    0,    0,    0,   24,  -94,   80,
+       0,    0,   20,    0,    0,    0,  -63,   16,  -59,    3,    2,  -64,    0,    0,    0,    8,
+    -122,   40,   98,    0,    0,  -64,    1,    0,    0,   16,  100, -127,    0,    0,    0,    0,
+      13,    0,    0,    0,   50,   30, -104,   20,   25,   17,   76, -112, -116,    9,   38,   71,
+     -58,    4,   67,    2,   70,    0,   74,  -96,   16,   72,   24,    1,   32,   98,    4, -128,
+    -116,   17,    0,   66,   70,    0,   72,   25,    1,  -96,  101,    4, -128, -104,   17,    0,
+    -126,  108,  -75,    6,   91,  -50,    1,    0,  121,   24,    0,    0,  -30,    0,    0,    0,
+      26,    3,   76, -112,   70,    2,   19,   52,   68,    0,   38,   42,  119,   99,  104,   97,
+     114,   95,  115,  105,  122,  101,   67,    4, -128,   26,   98,    0,  -45,   24,    4,    0,
+     -59,  -90,   45,  -51,  -19,  -85,  -52,  -83,  -82,  -19,  107,   46,   77,  -81,  108, -120,
+       1,   76,   99,   64,    0,   20,   -7,   32,  -56, -115,   76,  -18,   45, -115,   12,  100,
+    -116,   45,  -52,  -19,   12,  -60,  -82,   76,  110,   46,  -19,  -51,   13,  100,  -58,    5,
+     -57,   69,  -26,  -90, -122,    6,    7,    6,    4,    4,   69,   44,  108,  -82, -116,   12,
+     -28,  -51,   13, -124, -119,  -55,  -86,    9,  100,  -58,    5,  -57,   69,  -26,  -90, -122,
+       6,    7,   38,  101, -120,   48,    6,    6,   15,  -69,   50,  -71,  -71,  -76,   55,   55,
+       6,   49,   67, -120,   49,   64,  -58,   32,   97,  -92,   22,  102,   23,  -10,    5,   23,
+      54,  -74,   22,  118,   86,  -10,  -27,   22,  -42,   86,  -58,  105,  -20,  -83,  -51,   37,
+     -52, -115,   76,  -18,   45, -115,  -52,   69,  110,  -50, -123,  -82,  108, -114,  110,    8,
+      49,    6,  -53,   24,   48,   60,  -20,  -62,  -28,  -66,  -46,  -36,  -24,   24,  -44,   12,
+      33,  -58,  -64,   25, -125, -121, -120,   93, -104,  -36,   23,  -37, -101,  -37,   25,    3,
+    -101,   33,  -60,   24,   68,   99,   32,   49,  -79,   11, -109,   -5,   50,   99,  123,   11,
+     -93,   27,   66, -116,    1,   53,    6,    9,   21,  -69,   48,  -71,   47,  -78,  -73,   58,
+      49,  -74,   50,    6,   50,   67, -120,   49,  -80,  -58,  -32,  -94,   99,   23,   38,   -9,
+      21,  -58,  -58,  -10,   54,   22,   70, -105,  -10,  -26,   70,   65,    6,  102,    8,   49,
+       6,  -39,   24,  104,   76,  -20,  -62,  -28,  -66,  -62,  -28,  -28,  -62,  -14,   -8,  -16,
+      12,  -67,  -71,  -51,  -47, -123,  -71,  -47,    5,  -55,  -55, -123,  -27,   -7,   12,   33,
+     -58, -128,   27, -125, -114, -118,   93, -104,  -36,   23,  -36,   91, -102,   27,  -99,   12,
+      13,  -88,  -73,   52,   55,   58, -103,   33,  -60,   24,  124,   99,    0,    6,  116,  -20,
+     -62,  -28,  -66,  -32,  -34,  -46,  -36,  -24,  100,  -66,  -32,  -24,  -28,  120,  -88,   64,
+     -67,  -91,  -71,  -47,  -55,   12,   33,  -58,   64,   12,  -58,   96,   12,   24,  -48,   12,
+      17,  -58,  -96,   12, -120, -104,  -43,  -71, -115,  -47,  -91,  -67,  -71,   13,   17,  -58,
+     -32,   12,   24,  -71,  -96, -107,  -79,  -63, -107,  -55,  125, -103,  -43,  -71, -115,  -47,
+     -91,  -67,  -71,   89,   13,   17,  -58,   32,   13,   72,  -56,  -67,  -67,  -47,   13,   17,
+     -58,   96,   13, -104,  -92,  -71, -115,  -55, -107,  -75, -107,  -71,  -47,   13,   17,  -58,
+     -96,   13,   24,  -64,   12,   17,  -58,  -32,   13,   40,  -52,  -44,   12,   17,  -58,   32,
+      14, -104,  -52,  -43,  -75,  -75, -123,  -47,  -91,  -67,  -71,  -47, -103,  -85,  107,   11,
+      26,   27,  -85,  107,  -85,   99,   11,  -93,  123, -109,   27,   66, -116,    1,   29, -116,
+      65,  -62,  101,  -82,  -82,  109,  -24,  -83,   77,   44,  -51,  -83,   76,  110, -120,   50,
+       6,  115,   48,    6,  101,   48,    6,  117,   32,    1,   99,   96,    7,   67, -124,   49,
+       0,    3,    6,  120,   28,  -46,  -36,  -24, -122,   16,   99, -112,    7,   99,  -96,    7,
+      12,  -14, -122,   16,   99,  -64,    7,   99,  -96,    7,  124,  -34,  -38,  -36,  -46,  -32,
+     -34,  -24,  -54,  -36,  -24,   64,  -58,  -48,  -62,  -28,   24,   77,  -91,  -75,  -63,  -79,
+    -107, -127,   12,  -67,   12,  -83,  -84, -128,   80,    9,    5,    5,   13,   17,  -58,  -32,
+      15, -122,    8,   66,   53,  -60,   24,    3,   63,   24,    3,   80,   16,  -86,   33,  -58,
+      24,  -24,  -63,   24, -120, -126,   80,   13,   49,  -58,   96,   20,  -58,   96,   20, -124,
+    -118,    4,  -37, -101,  -37,  -39,   16,   99,   12,   74,   97,   12,   68,   65,  -88, -122,
+      24,   99,   96,   10,   99,   96,   10,   66,  -59,  -62, -116,  -19,   45, -116,  110, -120,
+      49,    6,  -88,   48,    6,  -94,   32,   84,   67, -116,   49,   72, -123,   49,   72,    5,
+     -95,  -94,   65,  -10,   86,   39,  -58,   86,   54,  -60,   24, -125,   85,   24,    3,   81,
+      16,  -86,   33,  -58,   24,  -80,  -62,   24,  -80, -126,   80,   53,   98,   99,  -77,  107,
+     115,  105,  123,   35,  -85,   99,   43,  115,   49,   99,   11,   59, -101, -101,   34,   12,
+      69,   21,   54,   54,  -69,   54, -105,   52,  -78,   50,   55,  -70,   41,  -63,  -47,   99,
+       4,   78,   46,  -20,  -84,   45,  108, -118,  -96,   52,  117,   70,  -28,  -26,  -66,  -54,
+     -16,  -32,  -34,  -28,  -24,  -66,  -20,  -62,  -28,  -90,   32,  -48,   84,   97, -101,   23,
+       6,  100,   80,  104,   68,  110,  -18,  -21,   77,   76,  -83,  108, -116,  -18,  107, -114,
+     -19, -115,  110,  110,   74,   96,    6,  125,   70,  -28,  -26,  -66,  -54,  -16,  -32,  -34,
+     -28,  -24,  -66,  -52,  -22,  -36,  -58,  -90,    8,  104,  -96,    6,  -67,   70,  -28,  -26,
+     -66,  -54,  -16,  -32,  -34,  -28,  -24,  -66,  -52,  -34,  -28,  -54,  -62,  -58,  -48,  -66,
+     -36,  -62,  -38,  -54,  -90,    8,  108,  -32,    6, -107,   70,  -28,  -26,  -66,  -54,  -16,
+     -32,  -34,  -28,  -24,  -66,  -52,  -34,  -28,  -54,  -62,  -58,  -48,  -90,    8,  112,   32,
+       7, -115,   70,  -28,  -26,  -66,  -54,  -16,  -32,  -34,  -28,  -24,  -66,  -28,  -54,  -56,
+     -22,  -58,  -54,  -90,    4,  119,  -48,  103,   68,  110,  -18,  -85,   12,   15,  -18,   77,
+    -114,  -18, -117,   46,   15,  -82,  108,   74, -128,    7,   61,   74,  -96,  -34,  -46,  -36,
+     -24,  100,  -90,    8,  123,  -48,    7,    0,  121,   24,    0,    0,   92,    0,    0,    0,
+      51,    8, -128,   28,  -60,  -31,   28,  102,   20,    1,   61, -120,   67,   56, -124,  -61,
+    -116,   66, -128,    7,  121,  120,    7,  115, -104,  113,   12,  -26,    0,   15,  -19,   16,
+      14,  -12, -128,   14,   51,   12,   66,   30,  -62,  -63,   29,  -50,  -95,   28,  102,   48,
+       5,   61, -120,   67,   56, -124, -125,   27,  -52,    3,   61,  -56,   67,   61, -116,    3,
+      61,  -52,  120, -116,  116,  112,    7,  123,    8,    7,  121,   72, -121,  112,  112,    7,
+     122,  112,    3,  118,  120, -121,  112,   32, -121,   25,  -52,   17,   14,  -20, -112,   14,
+     -31,   48,   15,  110,   48,   15,  -29,  -16,   14,  -16,   80,   14,   51,   16,  -60,   29,
+     -34,   33,   28,  -40,   33,   29,  -62,   97,   30,  102,   48, -119,   59,  -68, -125,   59,
+     -48,   67,   57,  -76,    3,   60,  -68, -125,   60, -124,    3,   59,  -52,  -16,   20,  118,
+      96,    7,  123,  104,    7,   55,  104, -121,  114,  104,    7,   55, -128, -121,  112, -112,
+    -121,  112,   96,    7,  118,   40,    7,  118,   -8,    5,  118,  120, -121,  119, -128, -121,
+      95,    8, -121,  113,   24, -121,  114, -104, -121,  121, -104, -127,   44,  -18,  -16,   14,
+     -18,  -32,   14,  -11,  -64,   14,  -20,   48,    3,   98,  -56,  -95,   28,  -28,  -95,   28,
+     -52,  -95,   28,  -28,  -95,   28,  -36,   97,   28,  -54,   33,   28,  -60, -127,   29,  -54,
+      97,    6,  -42, -112,   67,   57,  -56,   67,   57, -104,   67,   57,  -56,   67,   57,  -72,
+     -61,   56, -108,   67,   56, -120,    3,   59, -108,  -61,   47,  -68, -125,   60,   -4, -126,
+      59,  -44,    3,   59,  -80,  -61,   12,  -57,  105, -121,  112,   88, -121,  114,  112, -125,
+     116,  104,    7,  120,   96, -121,  116,   24, -121,  116,  -96, -121,   25,  -50,   83,   15,
+     -18,    0,   15,  -14,   80,   14,  -28, -112,   14,  -29,   64,   15,  -31,   32,   14,  -20,
+      80,   14,   51,   32,   40,   29,  -36,  -63,   30,  -62,   65,   30,  -46,   33,   28,  -36,
+    -127,   30,  -36,  -32,   28,  -28,  -31,   29,  -22,    1,   30,  102,   24,   81,   56,  -80,
+      67,   58, -100, -125,   59,  -52,   80,   36,  118,   96,    7,  123,  104,    7,   55,   96,
+    -121,  119,  120,    7,  120, -104,   81,   76,  -12, -112,   15,  -16,   80,   14,    0,    0,
+     113,   32,    0,    0,   56,    0,    0,    0,    6,   17,    6,   -1,   92,  -33, -111,  -60,
+      45,    4,   16,  -95,   65,   66,    8,   83,   90,  -33, -111,  -12,    3,  -53,  -30,    8,
+     -64, -124,   56, -115,   13,   40,   21,   16,   -3, -125,   67,    5,   11,   97,    5,   74,
+       5,   68,   -1,  -29,   32,  -51,  100,   27,   67, -126,   52,   66,   68,   48,   68,   51,
+    -103,    2,   82,   80, -115,   48,   33,   78,   99,    4,   73,    5,   68,   63,   16,   69,
+       0,  102,   17, -111,  127,   16,  -53,   67,   68,  127,   65,   53,  -62, -124,   56,  -51,
+     107,   14, -117,   68,   49, -100,  -61,    4,   72,   67,   68,  102,  -32,   84,   64,  -12,
+       3,  -53,  -30,    8,  -64, -124,   56, -115,   33,  112,  126,   36,   -7,   17,   49,   80,
+       2,  -15,   23, -115,   47,   81, -116,   38,    8,   20,   67,   45,  -64,  -28,   68,    6,
+     112,   84,   64,  -12,   35,  -51,  100,   13, -114,   68,   49, -102,   32,   80,   12,  -75,
+       0, -109,   19,   89,    0,   82,    1,  -47,  -65,   56, -115,   97,    7,   78,    5,   68,
+      -1,  -29,   32,  -51,  100,   -1,  -49,   20,  -39,    3,  -30,   71, -110,   63,   76,   78,
+     100,   11,   73,   65,   53,  -62, -124,   56,  -51,  107,    2,   73,    5,   68,  127,  -79,
+      56,  -64,  100,    9, -103,   31,   73,  126,   68,   12, -108,   64,   -4,   69,  -29,   75,
+      20,  -61,   57,   76, -128,   52,   68,    4,   97,   32,    0,    0,   54,    0,    0,    0,
+      19,    4,   65,   44,   16,    0,    0,    0,   20,    0,    0,    0,    4, -108,   66,   49,
+    -108,   67,   17,   20,   68,   25, -108,   68,   81, -112,   80,    4,   20,   12,  101,   36,
+       4,   32,    1,  -45,   80,   70,   66,    0,   18,   16,    6,   67,   25,    9,    1,   72,
+     -64,   24,   12,  101,   44,    5,   32,    1,  -46,   80,  -58,   82,    0,   18,   48,   13,
+     101,   36,    4,   32,    1,   18,   17,   99,    4,   32,    8, -126,   36,   24, -112,   49,
+      70,    0, -126,   32,    8, -126,   32,    8, -126,   36,   72,    0, -125,   17,  -64,   52,
+       0, -125,   17, -127,   25,   16,  -64,   96, -124,  -48,    6,    3,   48,   24,   49,  -72,
+       1,    1,   12,   70,  -80, -127,   55,    0, -125,   17,  103,  -16,   13,  -64,   96,    4,
+      26, -128,  -63,    0,   12,   70,  -92, -127,   24,   12,  -64,   96, -124,   26, -112,  -63,
+       0,   12,   70,  -84,   65,   25,   12,    0,    6,  -60,    0,    0,   13,    0,    0,    0,
+      91,    6,   32,   32, -123,   45,   67,   16, -100,  -62, -106,   65,    8,   84,   97,  -53,
+      48,    4,  -83,  -80,  101,   32,    2,   82,  -40,   50,   20,    1,   41,  108,   25, -116,
+    -128,   20,  -74,   12,   71,   64,   10,   91,    6,   36,   32, -123,   45,   67,   18, -112,
+       2,    0,    0,    0,    0,    0,    0,    0,   97,   32,    0,    0,   11,    0,    0,    0,
+      19,    4,  -63,   96,    4,  -32,   13,    0, -122,    3,    1,    0,    2,    0,    0,    0,
+     -26,   49,    0, -111,    1,    0,    0,    0,    1,   49,    0,    0,    2,    0,    0,    0,
+      91,    6,   32,   32,    5,    0,    0,    0,    0,    0,    0,    0,   97,   32,    0,    0,
+      11,    0,    0,    0,   19,    4,  -63,  121,   64,  -40,   55,  -63,  -32,  -64,  -32, -127,
+      12, -125,  112,   32,    5,    0,    0,    0,  -10,   65,    8,   78,   83, -103, -121, -128,
+      52,   22,   82,    8,   78,   83,  -43,    6,   50,    0,  -61,    0,    0,    0,    0,    0,
+      97,   32,    0,    0,   16,    0,    0,    0,   19,    4,    1,  121,  -61,  -64,  -32,    3,
+     -63,   96, -124,   23,    6,    3, -128,  -31,   64,    0,    0,    0,    4,    0,    0,    0,
+     -10,   49,   84,  -64,   98,   30,    5,   32,    8,   20,   99,   33,    3,   48,   12,    0,
+       1,   49,    0,    0,    3,    0,    0,    0,   91,    6,   32,   32, -123,   45, -125,   16,
+    -112,    2,    0,    0,    0,    0,    0,    0,   97,   32,    0,    0,   17,    0,    0,    0,
+      19,    4,    1,  125, -125,  -68,   97,   97,    0,    6,   32,   24, -116,  -16,  -60,   96,
+       0,   48,   28,    8,    4,    0,    0,    0,  -10,   49,   84,  -64,   98,   30,    5,   32,
+       8,   20,   99,   34,    3,   48,   12,    0,    1,   49,    0,    0,    4,    0,    0,    0,
+      91,    6,   32,   32, -123,   45,   67,   16, -112,  -62, -106,   97,    8,   72,    1,    0,
+       0,    0,    0,    0,   97,   32,    0,    0,    3,    0,    0,    0,   19,    4,  -63, -120,
+       1, -127,    4, -112, -127,    0,    0,    0,   97,   32,    0,    0,    9,    0,    0,    0,
+      19,    4,  -63,  120, -125,   39,   73,  -12, -115,   17,    3,    2,    8,   22,   48,  -64,
+     112,   32,    0,    0,    2,    0,    0,    0,    7,   80,   16,  -51,   20,   97,    0,    0,
+       0,    0,    0,    0,    0,    0,    0,    0,
+};
+
+const int bitCodeLength = 2776;
+
+#else
+
+const int8_t bitCode[] = {
+     -34,  -64,   23,   11,    0,    0,    0,    0,   44,    0,    0,    0, -116,   10,    0,    0,
+       0,    0,    0,    0,   -1,   -1,   -1,   -1,    0,    0,    0,    0,    1,   64,    4,    0,
+      96,    9,    0,    0,    2,   64,    4,    0,    3,    0,    0,    0,   66,   67,  -64,  -34,
+      33,   12,    0,    0,  -96,    2,    0,    0,    1,   16,    0,    0,   18,    0,    0,    0,
+       7, -127,   35, -111,   65,  -56,    4,   73,    6,   16,   50,   57, -110,    1, -124,   12,
+      37,    5,    8,   25,   30,    4, -117,   98, -128,   24,   69,    2,   66, -110,   11,   66,
+     -60,   16,   50,   20,   56,    8,   24,   73,   10,   50,   68,   36,   72,   10, -112,   33,
+      35,  -60,   82, -128,   12,   25,   33,  114,   36,    7,  -56, -120,   17,   98,  -88,  -96,
+     -88,   64,  -58,  -16,    1,    0,    0,    0,   73,   24,    0,    0,   24,    0,    0,    0,
+      11, -124,   -1,   -1,   -1,   -1,   31,  -64,   96, -127,  -16,   -1,   -1,   -1,   -1,    3,
+      24,   45,   32,    2,   16,    4,   65,   16,   36,   -2,   -1,   -1,   -1,  127,    0, -125,
+       5,   70,    0, -126,   32,    8, -126, -124,    0, -126,   32,    8, -126,  -60,   -1,   -1,
+      -1,   -1,   15,   96,  -80,   64,   -8,   -1,   -1,   -1,   -1,    1,   12,   22,    8,   -1,
+      -1,   -1,   -1,   63,    0,   11, -120,    0,    4,   65,   16,    4, -119,   -1,   -1,   -1,
+      -1,   31,  -64,   80,   88,   64,    4,  -64,   -1,   -1,   -1,   -1,   15,   96,    0,    0,
+    -119,   32,    0,    0,   34,    0,    0,    0,   50,   34, -120,    9,   32,  100, -123,    4,
+      19,   35,  -92, -124,    4,   19,   35,  -29, -124,  -95, -112,   20,   18,   76, -116, -116,
+      11, -124,  -60,   76,   16, -112,  -63,   28,    1,   24,   16,   48,   71,    0,   10,   36,
+     -52,    0,   16,   49,    4,   64,   70,   18,    0, -124,   28,   36,   77,   17,   37,   76,
+     126,  -22,   32,  -51,  100,   -5,   61, -114,    4,    0,   32,  -27,   46,  105, -118,   40,
+      97,  -14,   35,  -23,    7, -106,  -59,   17, -128,    9,  113,   26,  -65,  -49,   17,   49,
+      12,  -61,   64,   12,   45,  115,    4,    8,   61,    4, -115,    0, -108,   64,  -94,  -87,
+       8,   18,   64,   85,   17,  -98, -121,  -82,   50,   72,    1,   64,   89,   25,  -92,   32,
+     -96,  -83,    8,   82,   67,  -99,    9,    0,   -6, -118,   32, -127,   20,   14,    4,    0,
+      19,  -76,  112,    8,    7,  121,   24,    7,  116,  -80,    3,   58,  104,    3,  119,  120,
+       7,  119,   40, -121,   54,   96, -121,  116,  112, -121,  122,  -64, -121,   54,   56,    7,
+     119,  -88, -121,  114,    8,    7,  113,   72, -121,   13,  115,   80,   14,  109,  -48,   14,
+     122,   80,   14,  109, -112,   14,  120,  -96,    7,  120,  -96,    7,  115,   32,    7,  109,
+    -112,   14,  113,   96,    7,  122,   16,    7,  118,  -96,    7,  115,   32,    7,  109, -112,
+      14,  118,   64,    7,  122,   96,    7,  116,  -48,    6,  -23,   16,    7,  114, -128,    7,
+     122,   16,    7,  114, -128,    7,  109,  -32,   14,  115,   32,    7,  122,   96,    7,  116,
+     -48,    6,  -77,   16,    7,  114, -128,    7,   58,   15,  -92,   72,   32,   35,   68,   70,
+    -128,   29,   74,    0,   76,  -56,    0,    0,   64,    0,  -20,   80,    6, -128,   66,    8,
+       0,    0,    2,   96, -121,   82,    0,   21,   50,    0,    0,   16,    0,   59, -108,    3,
+     -80,   16,    2,    0, -128,    0,  -40,  -95,   36,  -64, -123,   12,    0,    0,    4,  -64,
+      14,  101,    1,   48,  100,    0,    0,   32,    0,  -40,  104,  -56,   29, -118,    3,  100,
+       8,    1,    0,   64,    0,  -20,   80,   34,   96,    3,    8,    0,    0,    2,   96, -121,
+      18,    1,   28,   64,    0,    0,   16,    0,   67,   20,   10,    0, -128,    0,    0,    0,
+      32,   24,  -94,   88,    0,    0,    4,    0,    0,    0,  -63,   16,    5,    3,    0,   64,
+       0,    0,    0,    8, -122,   40,   26,    0,   12,    3,    0,    0,    0,   48,   68,  -31,
+       0,   96,   32,    0,    0,    0, -128,   33,   10,    5,    0,   64,    1,    0,    0,   16,
+      12,   81,   60,   32,    0,   12,    0,    0, -128,   96, -120,   34,    6,    0,    0,   28,
+       0,    0,    0,   65,   22,    8,    0,    0,   13,    0,    0,    0,   50,   30, -104,   20,
+      25,   17,   76, -112, -116,    9,   38,   71,  -58,    4,   67,    2,   70,    0,   72,   24,
+       1,   32,   98,    4, -128, -116,   17,    0,   66,   70,    0,   72,   25,    1,  -96,  101,
+       4, -128, -104,   17,    0, -126,  108,  -75,    6,   91,  -50,    1,    0,    0,    0,    0,
+     121,   24,    0,    0,  -48,    0,    0,    0,   26,    3,   76, -112,   70,    2,   19,   68,
+      62,    8,  114,   35, -109,  123,   75,   35,    3,   25,   99,   11,  115,   59,    3,  -79,
+      43, -109, -101,   75,  123,  115,    3, -103,  113,  -63,  113, -111,  -71,  -87,  -95,  -63,
+    -127,    1,    1,   65,   17,   11, -101,   43,   35,    3,  121,  115,    3,   97,   98,  -78,
+     106,    2, -103,  113,  -63,  113, -111,  -71,  -87,  -95,  -63, -127,   73,   25,   34, -116,
+       1,  -64,  -61,  -82,   76,  110,   46,  -19,  -51, -115,   65,  -52,   16,   98,   12, -124,
+      49,   24,   24,  -87, -123,  -39, -123,  125,  -63, -123, -115,  -83, -123,  -99, -107,  125,
+     -71, -123,  -75, -107,  113,   26,  123,  107,  115,    9,  115,   35, -109,  123,   75,   35,
+     115, -111, -101,  115,  -95,   43, -101,  -93,   27,   66, -116,   65,   49,    6,    6,   15,
+     -69,   48,  -71,  -81,   52,   55,   58,    6,   53,   67, -120,   49,   64,  -58,   32,   33,
+      98,   23,   38,   -9,  -59,  -10,  -26,  118,  -58,  -64,  102,    8,   49,    6,  -53,   24,
+      48,   76,  -20,  -62,  -28,  -66,  -52,  -40,  -34,  -62,  -24, -122,   16,   99,  -32, -116,
+     -63,   64,  -59,   46,   76,  -18, -117,  -20,  -83,   78, -116,  -83, -116, -127,  -52,   16,
+      98,   12,  -96,   49, -120,  -24,  -40, -123,  -55,  125, -123,  -79,  -79,  -67, -115, -123,
+     -47,  -91,  -67,  -71,   81, -112, -127,   25,   66, -116,  -63,   52,    6,   20,   19,  -69,
+      48,  -71,  -81,   48,   57,  -71,  -80,   60,   62,   60,   67,  111,  110,  115,  116,   97,
+     110,  116,   65,  114,  114,   97,  121,   62,   67, -120,   49,  -80,  -58,  -32,  -94,   98,
+      23,   38,   -9,    5,   -9, -106,  -26,   70,   39,   67,    3,  -22,   45,  -51, -115,   78,
+     102,    8,   49,    6,  -39,   24,  104,  116,  -20,  -62,  -28,  -66,  -32,  -34,  -46,  -36,
+     -24,  100,  -66,  -32,  -24,  -28,  120,  -88,   64,  -67,  -91,  -71,  -47,  -55,   12,   33,
+     -58, -128,   27, -125, -114,    1,  -51,   16,   97,   12,   62,   34,  102,  117,  110,   99,
+     116,  105,  111,  110,   67, -124,   49,    8,    3,   70,   46,  104,  101,  108,  112,  101,
+     114,   95,  102,  117,  110,   99,  116,  105,  111,  110,   86,   67, -124,   49,   24,    3,
+      18,  114,  111,  111,  116,   67, -124,   49,   40,    3,   38,  105,  110,   99,  114,  101,
+     109,  101,  110,  116,   67, -124,   49,   56,    3,    6,   48,   67, -124,   49,   72,    3,
+      10,   51,   53,   67, -124,   49,   88,    3,   38,  115,  117,  109,  109,   97,  116,  105,
+     111,  110,  116,  -26,  -22,  -38, -126,  -58,  -58,  -22,  -38,  -22,  -40,  -62,  -24,  -34,
+     -28, -122,   16,   99,  -32,    6,   99,   48,  112, -103,  -85,  107,   27,  122,  107,   19,
+      75,  115,   43, -109,   27,  -94, -116,   65,   27, -116,  -63,   55,    6,  111,   32,    1,
+      99,    0,    7,   67, -124,   49,  -48,   24,  -32,  113,   72,  115,  -93,   27,   66, -116,
+     -63,   28, -116,    1,   29,   48,  -56,   27,   66, -116, -127,   29, -116,    1,   29,  -16,
+     121,  107,  115,   75, -125,  123,  -93,   43,  115,  -93,    3,   25,   67,   11, -109,   99,
+      52, -107,  -42,    6,  -57,   86,    6,   50,  -12,   50,  -76,  -78,    2,   66,   37,   20,
+      20,   52,   68,   24, -125,   60,   24,   34,    8,  -45,   16,   99,   12,  -16,   96,   12,
+     -12,   64, -104, -122,   24,   99,   64,    7,   99,  -64,    7,  -62,   52,  -60,   24, -125,
+      62,   24, -125,   62,   16,   38,   18,  108,  111,  110,  103,   67, -116,   49,   -8, -125,
+      49,  -32,    3,   97,   26,   98, -116,    1,   40, -116,    1,   40,    8,   19,   11,   51,
+     -74,  -73,   48,  -70,   33,  -58,   24, -120,  -62,   24,  -16, -127,   48,   13,   49,  -58,
+      96,   20,  -58,   96,   20, -124, -119,    6,  -39,   91,  -99,   24,   91,  -39,   16,   99,
+      12,   74,   97,   12,   -8,   64, -104, -122,   24,   99,   96,   10,   99,   96,   10,  -62,
+      84, -123, -115,  -51,  -82,  -51,   37, -115,  -84,  -52, -115,  110,   74,   16,  -12,   24,
+    -127, -109,   11,   59,  107,   11, -101,   34,   16,   71,  -99,   17,  -71,  -71,  -81,   50,
+      60,  -72,   55,   57,  -70,   47,  -69,   48,  -71,   41, -120,  -46,   60,   82, -123,  109,
+      94,  -95,   17,  -71,  -71,  -81,   55,   49,  -75,  -78,   49,  -70,  -81,   57,  -74,   55,
+     -70,  -71,   41,    1,   24,  -12,   25, -111, -101,   -5,   42,  -61, -125,  123, -109,  -93,
+      -5,   50,  -85,  115,   27, -101,   34, -120,    1,   25,  -12,   26, -111, -101,   -5,   42,
+     -61, -125,  123, -109,  -93,   -5,   50,  123, -109,   43,   11,   27,   67,   -5,  114,   11,
+     107,   43, -101,   34, -104,    1,   26,   84,   26, -111, -101,   -5,   42,  -61, -125,  123,
+    -109,  -93,   -5,   50,  123, -109,   43,   11,   27,   67, -101,   34,  -88,    1,   27,   52,
+      26, -111, -101,   -5,   42,  -61, -125,  123, -109,  -93,   -5, -110,   43,   35,  -85,   27,
+      43, -101,   18,  -60,   65,  -97,   17,  -71,  -71,  -81,   50,   60,  -72,   55,   57,  -70,
+      47,  -70,   60,  -72,  -78,   41, -127,   28,  -12,   40, -127,  122,   75,  115,  -93, -109,
+    -103,   34,  -44,  -63,   29,    0,    0,    0,  121,   24,    0,    0,   92,    0,    0,    0,
+      51,    8, -128,   28,  -60,  -31,   28,  102,   20,    1,   61, -120,   67,   56, -124,  -61,
+    -116,   66, -128,    7,  121,  120,    7,  115, -104,  113,   12,  -26,    0,   15,  -19,   16,
+      14,  -12, -128,   14,   51,   12,   66,   30,  -62,  -63,   29,  -50,  -95,   28,  102,   48,
+       5,   61, -120,   67,   56, -124, -125,   27,  -52,    3,   61,  -56,   67,   61, -116,    3,
+      61,  -52,  120, -116,  116,  112,    7,  123,    8,    7,  121,   72, -121,  112,  112,    7,
+     122,  112,    3,  118,  120, -121,  112,   32, -121,   25,  -52,   17,   14,  -20, -112,   14,
+     -31,   48,   15,  110,   48,   15,  -29,  -16,   14,  -16,   80,   14,   51,   16,  -60,   29,
+     -34,   33,   28,  -40,   33,   29,  -62,   97,   30,  102,   48, -119,   59,  -68, -125,   59,
+     -48,   67,   57,  -76,    3,   60,  -68, -125,   60, -124,    3,   59,  -52,  -16,   20,  118,
+      96,    7,  123,  104,    7,   55,  104, -121,  114,  104,    7,   55, -128, -121,  112, -112,
+    -121,  112,   96,    7,  118,   40,    7,  118,   -8,    5,  118,  120, -121,  119, -128, -121,
+      95,    8, -121,  113,   24, -121,  114, -104, -121,  121, -104, -127,   44,  -18,  -16,   14,
+     -18,  -32,   14,  -11,  -64,   14,  -20,   48,    3,   98,  -56,  -95,   28,  -28,  -95,   28,
+     -52,  -95,   28,  -28,  -95,   28,  -36,   97,   28,  -54,   33,   28,  -60, -127,   29,  -54,
+      97,    6,  -42, -112,   67,   57,  -56,   67,   57, -104,   67,   57,  -56,   67,   57,  -72,
+     -61,   56, -108,   67,   56, -120,    3,   59, -108,  -61,   47,  -68, -125,   60,   -4, -126,
+      59,  -44,    3,   59,  -80,  -61,   12,  -57,  105, -121,  112,   88, -121,  114,  112, -125,
+     116,  104,    7,  120,   96, -121,  116,   24, -121,  116,  -96, -121,   25,  -50,   83,   15,
+     -18,    0,   15,  -14,   80,   14,  -28, -112,   14,  -29,   64,   15,  -31,   32,   14,  -20,
+      80,   14,   51,   32,   40,   29,  -36,  -63,   30,  -62,   65,   30,  -46,   33,   28,  -36,
+    -127,   30,  -36,  -32,   28,  -28,  -31,   29,  -22,    1,   30,  102,   24,   81,   56,  -80,
+      67,   58, -100, -125,   59,  -52,   80,   36,  118,   96,    7,  123,  104,    7,   55,   96,
+    -121,  119,  120,    7,  120, -104,   81,   76,  -12, -112,   15,  -16,   80,   14,    0,    0,
+     113,   32,    0,    0,   56,    0,    0,    0,    6,   17,    6,   -1,   92,  -33, -111,  -60,
+      45,    4,   16,  -95,   65,   66,    8,   83,   90,  -33, -111,  -12,    3,  -53,  -30,    8,
+     -64, -124,   56, -115,   13,   40,   21,   16,   -3, -125,   67,    5,   11,   97,    5,   74,
+       5,   68,   -1,  -29,   32,  -51,  100,   27,   67, -126,   52,   66,   68,   48,   68,   51,
+    -103,    2,   82,   80, -115,   48,   33,   78,   99,    4,   73,    5,   68,   63,   16,   69,
+       0,  102,   17, -111,  127,   16,  -53,   67,   68,  127,   65,   53,  -62, -124,   56,  -51,
+     107,   14, -117,   68,   49, -100,  -61,    4,   72,   67,   68,  102,  -32,   84,   64,  -12,
+       3,  -53,  -30,    8,  -64, -124,   56, -115,   33,  112,  126,   36,   -7,   17,   49,   80,
+       2,  -15,   23, -115,   47,   81, -116,   38,    8,   20,   67,   45,  -64,  -28,   68,    6,
+     112,   84,   64,  -12,   35,  -51,  100,   13, -114,   68,   49, -102,   32,   80,   12,  -75,
+       0, -109,   19,   89,    0,   82,    1,  -47,  -65,   56, -115,   97,    7,   78,    5,   68,
+      -1,  -29,   32,  -51,  100,   -1,  -49,   20,  -39,    3,  -30,   71, -110,   63,   76,   78,
+     100,   11,   73,   65,   53,  -62, -124,   56,  -51,  107,    2,   73,    5,   68,  127,  -79,
+      56,  -64,  100,    9, -103,   31,   73,  126,   68,   12, -108,   64,   -4,   69,  -29,   75,
+      20,  -61,   57,   76, -128,   52,   68,    4,   97,   32,    0,    0,   55,    0,    0,    0,
+      19,    4,   65,   44,   16,    0,    0,    0,   21,    0,    0,    0,    4, -108,   64,   41,
+      20,   67,   57,   20,   68,   73,   20,    5,    9,  101,   80,    2,   69,   64,  -63,   80,
+      70,   66,    8, -109,   48,    6,   67,   25,   75,   33,   76, -128,   52, -108,  -79,   20,
+     -62,    4,  112,   67,   25,    9,   33,   76,   66,   25,   12,  101,   36, -124,   48,    9,
+     100,   48, -108, -111,   16,  -62,   36,   76,   68, -116,   17, -128,   32,    8, -110,   96,
+      64,  -58,   24,    1,    8, -126,   32,    8, -126,   32,    8, -110,   32,    1,    0,    0,
+    -125,   17,    0,   55,    0, -125,   17,   65,   25,   16,  -64,   96, -124,  -64,    6,    3,
+      48,   24,   49,  -76,    1,    1,   12,   70,  -84,   65,   55,    0, -125,   17,  106,  -32,
+      13,  -64,   96,   68,   26,  124,    3,   48,   24,   97,    6,   96,   48,    0, -125,   17,
+     103,   16,    6,    3,   48,   24, -127,    6,   98,   48,    0,   24,   16,    3,    0,    0,
+      13,    0,    0,    0,   91,    6,   32,  -16, -125,   45,   67,   16, -124,  -62, -106,   65,
+       8,   72,   97,  -53,   48,    4,  -89,  -80,  101,   32,    2,   63,  -40,   50,   20, -127,
+      31,  108,   25, -116,  -64,   15,  -74,   12,   71,  -32,    7,   91,    6,   36,  -16, -125,
+      45,   67,   18,   -8,    1,    0,    0,    0,    0,    0,    0,    0,   97,   32,    0,    0,
+      11,    0,    0,    0,   19,    4,  -63,   96,    4,  -64,   13,    0, -122,    3,    1,    0,
+       2,    0,    0,    0,  -58,   49,    0, -111,    1,    0,    0,    0,    1,   49,    0,    0,
+       2,    0,    0,    0,   91,    6,   32,  -16,    3,    0,    0,    0,    0,    0,    0,    0,
+      97,   32,    0,    0,   15,    0,    0,    0,   19,    4,   65,   44,   16,    0,    0,    0,
+       1,    0,    0,    0,    4, -108,    0,    0,  -57,    1,   97,   94,    7, -125,   -5,   30,
+      72,   48,    8,    7,    2,    0,    0,    0,    5,    0,    0,    0,  -26,   65,    8,   78,
+      83,   25, -121, -128,   52,    6,   82,    8,   78,   83,  -43,  -10,   49,    0,  -61,    0,
+       0,    0,    0,    0,   97,   32,    0,    0,   15,    0,    0,    0,   19,    4,    1,  113,
+     -61,  -68,   14,    4, -125,   17,  -36,   55,    0,   24,   14,    4,    4,    0,    0,    0,
+     -42,   49,   84,  -64,   98,   28,    5,   32,    8,   20,   99,   31,    3,   48,   12,    0,
+       1,   49,    0,    0,    3,    0,    0,    0,   91,    6,   32,  -16, -125,   45, -125,   16,
+      -8,    1,    0,    0,    0,    0,    0,    0,   97,   32,    0,    0,   17,    0,    0,    0,
+      19,    4,    1,  117, -125,  -72,   97,  -97,    7, -126,  -63,    8,   14,   12,    6,    0,
+     -61, -127,    0,    0,    4,    0,    0,    0,  -42,   49,   84,  -64,   98,   28,    5,   32,
+       8,   20,   99,   32,    3,   48,   12,    0,    1,   49,    0,    0,    4,    0,    0,    0,
+      91,    6,   32,  -16, -125,   45,   67,   16,   -8,  -63, -106,   97,    8,   -4,    0,    0,
+       0,    0,    0,    0,   97,   32,    0,    0,    3,    0,    0,    0,   19,    4,  -63, -120,
+       1, -127,    4, -112, -127,    0,    0,    0,   97,   32,    0,    0,    9,    0,    0,    0,
+      19,    4,  -63,  120,    3,   55,   73,  -44, -115,   17,    3,    2,    8,   22,   15,  -61,
+    -127,    0,    0,    0,    2,    0,    0,    0,    7,   80,   16,  -51,   20,   97,    0,    0,
+       0,    0,    0,    0,    0,    0,    0,    0,
+};
+
+const int bitCodeLength = 2744;
+
+#endif
diff --git a/renderscript/Android.bp b/renderscript/Android.bp
index ba90f2c..ed19a37 100644
--- a/renderscript/Android.bp
+++ b/renderscript/Android.bp
@@ -2,4 +2,5 @@
 subdirs = [
     "1.0",
     "1.0/default",
+    "1.0/vts/functional",
 ]
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/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 2223022..166ad96 100644
--- a/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
@@ -176,6 +176,176 @@
   };
 
   /**
+   * Status codes (IEEE Std 802.11-2016, 9.4.1.9, Table 9-46).
+   */
+  enum StatusCode : uint32_t {
+    SUCCESS = 0,
+    UNSPECIFIED_FAILURE = 1,
+    TDLS_WAKEUP_ALTERNATE = 2,
+    TDLS_WAKEUP_REJECT = 3,
+    SECURITY_DISABLED = 5,
+    UNACCEPTABLE_LIFETIME = 6,
+    NOT_IN_SAME_BSS = 7,
+    CAPS_UNSUPPORTED = 10,
+    REASSOC_NO_ASSOC = 11,
+    ASSOC_DENIED_UNSPEC = 12,
+    NOT_SUPPORTED_AUTH_ALG = 13,
+    UNKNOWN_AUTH_TRANSACTION = 14,
+    CHALLENGE_FAIL = 15,
+    AUTH_TIMEOUT = 16,
+    AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+    ASSOC_DENIED_RATES = 18,
+    ASSOC_DENIED_NOSHORT = 19,
+    SPEC_MGMT_REQUIRED = 22,
+    PWR_CAPABILITY_NOT_VALID = 23,
+    SUPPORTED_CHANNEL_NOT_VALID = 24,
+    ASSOC_DENIED_NO_SHORT_SLOT_TIME = 25,
+    ASSOC_DENIED_NO_HT = 27,
+    R0KH_UNREACHABLE = 28,
+    ASSOC_DENIED_NO_PCO = 29,
+    ASSOC_REJECTED_TEMPORARILY = 30,
+    ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
+    UNSPECIFIED_QOS_FAILURE = 32,
+    DENIED_INSUFFICIENT_BANDWIDTH = 33,
+    DENIED_POOR_CHANNEL_CONDITIONS = 34,
+    DENIED_QOS_NOT_SUPPORTED = 35,
+    REQUEST_DECLINED = 37,
+    INVALID_PARAMETERS = 38,
+    REJECTED_WITH_SUGGESTED_CHANGES = 39,
+    INVALID_IE = 40,
+    GROUP_CIPHER_NOT_VALID = 41,
+    PAIRWISE_CIPHER_NOT_VALID = 42,
+    AKMP_NOT_VALID = 43,
+    UNSUPPORTED_RSN_IE_VERSION = 44,
+    INVALID_RSN_IE_CAPAB = 45,
+    CIPHER_REJECTED_PER_POLICY = 46,
+    TS_NOT_CREATED = 47,
+    DIRECT_LINK_NOT_ALLOWED = 48,
+    DEST_STA_NOT_PRESENT = 49,
+    DEST_STA_NOT_QOS_STA = 50,
+    ASSOC_DENIED_LISTEN_INT_TOO_LARGE = 51,
+    INVALID_FT_ACTION_FRAME_COUNT = 52,
+    INVALID_PMKID = 53,
+    INVALID_MDIE = 54,
+    INVALID_FTIE = 55,
+    REQUESTED_TCLAS_NOT_SUPPORTED = 56,
+    INSUFFICIENT_TCLAS_PROCESSING_RESOURCES = 57,
+    TRY_ANOTHER_BSS = 58,
+    GAS_ADV_PROTO_NOT_SUPPORTED = 59,
+    NO_OUTSTANDING_GAS_REQ = 60,
+    GAS_RESP_NOT_RECEIVED = 61,
+    STA_TIMED_OUT_WAITING_FOR_GAS_RESP = 62,
+    GAS_RESP_LARGER_THAN_LIMIT = 63,
+    REQ_REFUSED_HOME = 64,
+    ADV_SRV_UNREACHABLE = 65,
+    REQ_REFUSED_SSPN = 67,
+    REQ_REFUSED_UNAUTH_ACCESS = 68,
+    INVALID_RSNIE = 72,
+    U_APSD_COEX_NOT_SUPPORTED = 73,
+    U_APSD_COEX_MODE_NOT_SUPPORTED = 74,
+    BAD_INTERVAL_WITH_U_APSD_COEX = 75,
+    ANTI_CLOGGING_TOKEN_REQ = 76,
+    FINITE_CYCLIC_GROUP_NOT_SUPPORTED = 77,
+    CANNOT_FIND_ALT_TBTT = 78,
+    TRANSMISSION_FAILURE = 79,
+    REQ_TCLAS_NOT_SUPPORTED = 80,
+    TCLAS_RESOURCES_EXCHAUSTED = 81,
+    REJECTED_WITH_SUGGESTED_BSS_TRANSITION = 82,
+    REJECT_WITH_SCHEDULE = 83,
+    REJECT_NO_WAKEUP_SPECIFIED = 84,
+    SUCCESS_POWER_SAVE_MODE = 85,
+    PENDING_ADMITTING_FST_SESSION = 86,
+    PERFORMING_FST_NOW = 87,
+    PENDING_GAP_IN_BA_WINDOW = 88,
+    REJECT_U_PID_SETTING = 89,
+    REFUSED_EXTERNAL_REASON = 92,
+    REFUSED_AP_OUT_OF_MEMORY = 93,
+    REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED = 94,
+    QUERY_RESP_OUTSTANDING = 95,
+    REJECT_DSE_BAND = 96,
+    TCLAS_PROCESSING_TERMINATED = 97,
+    TS_SCHEDULE_CONFLICT = 98,
+    DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
+    MCCAOP_RESERVATION_CONFLICT = 100,
+    MAF_LIMIT_EXCEEDED = 101,
+    MCCA_TRACK_LIMIT_EXCEEDED = 102,
+    DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
+    ASSOC_DENIED_NO_VHT = 104,
+    ENABLEMENT_DENIED = 105,
+    RESTRICTION_FROM_AUTHORIZED_GDB = 106,
+    AUTHORIZATION_DEENABLED = 107,
+    FILS_AUTHENTICATION_FAILURE = 112,
+    UNKNOWN_AUTHENTICATION_SERVER = 113
+  };
+
+  /**
+   * Reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45).
+   */
+  enum ReasonCode : uint32_t {
+    UNSPECIFIED = 1,
+    PREV_AUTH_NOT_VALID = 2,
+    DEAUTH_LEAVING = 3,
+    DISASSOC_DUE_TO_INACTIVITY = 4,
+    DISASSOC_AP_BUSY = 5,
+    CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+    CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+    DISASSOC_STA_HAS_LEFT = 8,
+    STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+    PWR_CAPABILITY_NOT_VALID = 10,
+    SUPPORTED_CHANNEL_NOT_VALID = 11,
+    BSS_TRANSITION_DISASSOC = 12,
+    INVALID_IE = 13,
+    MICHAEL_MIC_FAILURE = 14,
+    FOURWAY_HANDSHAKE_TIMEOUT = 15,
+    GROUP_KEY_UPDATE_TIMEOUT = 16,
+    IE_IN_4WAY_DIFFERS = 17,
+    GROUP_CIPHER_NOT_VALID = 18,
+    PAIRWISE_CIPHER_NOT_VALID = 19,
+    AKMP_NOT_VALID = 20,
+    UNSUPPORTED_RSN_IE_VERSION = 21,
+    INVALID_RSN_IE_CAPAB = 22,
+    IEEE_802_1X_AUTH_FAILED = 23,
+    CIPHER_SUITE_REJECTED = 24,
+    TDLS_TEARDOWN_UNREACHABLE = 25,
+    TDLS_TEARDOWN_UNSPECIFIED = 26,
+    SSP_REQUESTED_DISASSOC = 27,
+    NO_SSP_ROAMING_AGREEMENT = 28,
+    BAD_CIPHER_OR_AKM = 29,
+    NOT_AUTHORIZED_THIS_LOCATION = 30,
+    SERVICE_CHANGE_PRECLUDES_TS = 31,
+    UNSPECIFIED_QOS_REASON = 32,
+    NOT_ENOUGH_BANDWIDTH = 33,
+    DISASSOC_LOW_ACK = 34,
+    EXCEEDED_TXOP = 35,
+    STA_LEAVING = 36,
+    END_TS_BA_DLS = 37,
+    UNKNOWN_TS_BA = 38,
+    TIMEOUT = 39,
+    PEERKEY_MISMATCH = 45,
+    AUTHORIZED_ACCESS_LIMIT_REACHED = 46,
+    EXTERNAL_SERVICE_REQUIREMENTS = 47,
+    INVALID_FT_ACTION_FRAME_COUNT = 48,
+    INVALID_PMKID = 49,
+    INVALID_MDE = 50,
+    INVALID_FTE = 51,
+    MESH_PEERING_CANCELLED = 52,
+    MESH_MAX_PEERS = 53,
+    MESH_CONFIG_POLICY_VIOLATION = 54,
+    MESH_CLOSE_RCVD = 55,
+    MESH_MAX_RETRIES = 56,
+    MESH_CONFIRM_TIMEOUT = 57,
+    MESH_INVALID_GTK = 58,
+    MESH_INCONSISTENT_PARAMS = 59,
+    MESH_INVALID_SECURITY_CAP = 60,
+    MESH_PATH_ERROR_NO_PROXY_INFO = 61,
+    MESH_PATH_ERROR_NO_FORWARDING_INFO = 62,
+    MESH_PATH_ERROR_DEST_UNREACHABLE = 63,
+    MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64,
+    MESH_CHANNEL_SWITCH_REGULATORY_REQ = 65,
+    MESH_CHANNEL_SWITCH_UNSPECIFIED = 66
+  };
+
+  /**
    * Used to indicate that a new network has been added.
    *
    * @param id Network ID allocated to the corresponding network.
@@ -268,7 +438,7 @@
    *        from access point. Refer to section 8.4.1.7 of IEEE802.11 spec.
    */
   oneway onDisconnected(
-          Bssid bssid, bool locallyGenerated, uint32_t reasonCode);
+          Bssid bssid, bool locallyGenerated, ReasonCode reasonCode);
 
   /**
    * Used to indicate an association rejection recieved from the AP
@@ -281,7 +451,7 @@
    * @param timedOut Whether failure is due to timeout rather
    *        than explicit rejection response from the AP.
    */
-  oneway onAssociationRejected(Bssid bssid, uint32_t statusCode, bool timedOut);
+  oneway onAssociationRejected(Bssid bssid, StatusCode statusCode, bool timedOut);
 
   /**
    * Used to indicate the timeout of authentication to an AP.