Merge "Print test information to the target device's logcat" into oc-dr1-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 01b5e7b..14616e4 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -55,4 +55,5 @@
 $(call add-clean-step, rm -rf $(OUT)/soong/.intermediates/)
 $(call add-clean-step, rm -rf $(OUT_DIR)/soong/.intermediates/hardware/interfaces/)
 $(call add-clean-step, rm -rf $(OUT_DIR)/soong/.intermediates/hardware/interfaces/)
-$(call add-clean-step, find $(PRODUCT_OUT)/system $(PRODUCT_OUT)/vendor -type f -name "android\.hardware\.configstore*" -print0 | xargs -0 rm -f)
\ No newline at end of file
+$(call add-clean-step, find $(PRODUCT_OUT)/system $(PRODUCT_OUT)/vendor -type f -name "android\.hardware\.configstore*" -print0 | xargs -0 rm -f)
+$(call add-clean-step, find $(PRODUCT_OUT)/system $(PRODUCT_OUT)/vendor -type f -name "android\.hardware\.configstore\@1\.1*" -print0 | xargs -0 rm -f)
diff --git a/audio/effect/2.0/xml/audio_effects_conf_V2_0.xsd b/audio/effect/2.0/xml/audio_effects_conf_V2_0.xsd
deleted file mode 100644
index 64647de..0000000
--- a/audio/effect/2.0/xml/audio_effects_conf_V2_0.xsd
+++ /dev/null
@@ -1,238 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-           targetNamespace="http://schemas.android.com/audio/audio_effects_conf/v2_0"
-           xmlns:aec="http://schemas.android.com/audio/audio_effects_conf/v2_0"
-           elementFormDefault="qualified">
-
-  <!-- Simple types -->
-  <xs:simpleType name="versionType">
-    <xs:restriction base="xs:decimal">
-      <xs:enumeration value="2.0"/>
-    </xs:restriction>
-  </xs:simpleType>
-  <xs:simpleType name="uuidType">
-    <xs:restriction base="xs:string">
-      <xs:pattern value="[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}"/>
-    </xs:restriction>
-  </xs:simpleType>
-  <xs:simpleType name="streamInputType">
-    <xs:restriction base="xs:string">
-      <xs:enumeration value="mic"/>
-      <xs:enumeration value="voice_uplink"/>
-      <xs:enumeration value="voice_downlink"/>
-      <xs:enumeration value="voice_call"/>
-      <xs:enumeration value="camcorder"/>
-      <xs:enumeration value="voice_recognition"/>
-      <xs:enumeration value="voice_communication"/>
-      <xs:enumeration value="unprocessed"/>
-    </xs:restriction>
-  </xs:simpleType>
-  <xs:simpleType name="streamOutputType">
-    <xs:restriction base="xs:string">
-      <xs:enumeration value="default"/>
-      <xs:enumeration value="voice_call"/>
-      <xs:enumeration value="system"/>
-      <xs:enumeration value="ring"/>
-      <xs:enumeration value="music"/>
-      <xs:enumeration value="alarm"/>
-      <xs:enumeration value="notification"/>
-      <xs:enumeration value="bluetooth_sco"/>
-      <xs:enumeration value="enforced_audible"/>
-      <xs:enumeration value="dtmf"/>
-      <xs:enumeration value="tts"/>
-    </xs:restriction>
-  </xs:simpleType>
-
-  <!-- Complex types -->
-  <xs:complexType name="libraryType">
-    <xs:annotation>
-      <xs:documentation xml:lang="en">
-        List of effect libraries to load. Each library element must have "name" and
-        "path" attributes. The latter is giving the full path of the library .so file.
-
-        Example:
-
-        <library name="name" path="/vendor/lib/soundfx/lib.so"/>
-
-      </xs:documentation>
-    </xs:annotation>
-    <xs:sequence>
-      <xs:element name="library" minOccurs="0" maxOccurs="unbounded">
-        <xs:complexType>
-          <xs:attribute name="name" type="xs:string" use="required"/>
-          <xs:attribute name="path" type="xs:string" use="required"/>
-        </xs:complexType>
-      </xs:element>
-    </xs:sequence>
-  </xs:complexType>
-  <xs:complexType name="effectImplType">
-    <xs:attribute name="library" type="xs:string" use="required"/>
-    <xs:attribute name="uuid" type="aec:uuidType" use="required"/>
-  </xs:complexType>
-  <xs:complexType name="effectProxyType">
-    <xs:complexContent>
-      <xs:extension base="aec:effectImplType">
-        <xs:sequence>
-          <xs:element name="libsw" type="aec:effectImplType" minOccurs="0" maxOccurs="1"/>
-          <xs:element name="libhw" type="aec:effectImplType" minOccurs="0" maxOccurs="1"/>
-        </xs:sequence>
-        <xs:attribute name="name" type="xs:string" use="required"/>
-      </xs:extension>
-    </xs:complexContent>
-  </xs:complexType>
-  <xs:complexType name="effectType">
-    <xs:annotation>
-      <xs:documentation xml:lang="en">
-        List of effects to load. Each effect element must contain "name",
-        "library", and "uuid" attrs. The value of the "library" attr must
-        correspond to the name of a "library" element. The name of the effect
-        element is indicative, only the value of the "uuid" element designates
-        the effect for the audio framework.  The uuid is the implementation
-        specific UUID as specified by the effect vendor. This is not the generic
-        effect type UUID.
-
-        For effect proxy implementations, SW and HW implemetations of the effect
-        can be specified.
-
-        Example:
-
-        <effect name="name" library="lib" uuid="uuuu"/>
-        <effect name="proxied" library="proxy" uuid="xxxx">
-            <libsw library="sw_bundle" uuid="yyyy"/>
-            <libhw library="offload_bundle" uuid="zzzz"/>
-        </effect>
-
-      </xs:documentation>
-    </xs:annotation>
-    <xs:sequence>
-      <xs:element name="effect" type="aec:effectProxyType" minOccurs="0" maxOccurs="unbounded"/>
-    </xs:sequence>
-  </xs:complexType>
-  <xs:complexType name="streamProcessingType">
-    <xs:sequence>
-      <xs:element name="apply" minOccurs="0" maxOccurs="unbounded">
-        <xs:complexType>
-          <xs:attribute name="effect" type="xs:string" use="required"/>
-        </xs:complexType>
-      </xs:element>
-    </xs:sequence>
-  </xs:complexType>
-  <xs:complexType name="streamPreprocessType">
-    <xs:annotation>
-      <xs:documentation xml:lang="en">
-        Audio preprocessing configuration. The processing configuration consists
-        of a list of elements each describing processing settings for a given
-        input stream. Valid input stream types are listed in "streamInputType".
-
-        Each stream element contains a list of "apply" elements. The value of the
-        "effect" attr must correspond to the name of an "effect" element.
-
-        Example:
-
-        <stream type="voice_communication">
-            <apply effect="effect1"/>
-            <apply effect="effect2"/>
-        </stream>
-
-      </xs:documentation>
-    </xs:annotation>
-    <xs:complexContent>
-      <xs:extension base="aec:streamProcessingType">
-        <xs:attribute name="type" type="aec:streamInputType" use="required"/>
-      </xs:extension>
-    </xs:complexContent>
-  </xs:complexType>
-  <xs:complexType name="streamPostprocessType">
-    <xs:annotation>
-      <xs:documentation xml:lang="en">
-        Audio postprocessing configuration. The processing configuration consists
-        of a list of elements each describing processing settings for a given
-        output stream. Valid output stream types are listed in "streamOutputType".
-
-        Each stream element contains a list of "apply" elements. The value of the
-        "effect" attr must correspond to the name of an "effect" element.
-
-        Example:
-
-        <stream type="music">
-            <apply effect="effect1"/>
-        </stream>
-
-      </xs:documentation>
-    </xs:annotation>
-    <xs:complexContent>
-      <xs:extension base="aec:streamProcessingType">
-        <xs:attribute name="type" type="aec:streamOutputType" use="required"/>
-      </xs:extension>
-    </xs:complexContent>
-  </xs:complexType>
-
-  <!-- Root element -->
-  <xs:element name="audio_effects_conf">
-    <xs:complexType>
-      <xs:sequence>
-        <xs:element name="libraries" type="aec:libraryType"/>
-        <xs:element name="effects" type="aec:effectType"/>
-        <xs:element name="postprocess" minOccurs="0" maxOccurs="1">
-          <xs:complexType>
-            <xs:sequence>
-              <xs:element name="stream" type="aec:streamPostprocessType" minOccurs="0" maxOccurs="unbounded"/>
-            </xs:sequence>
-          </xs:complexType>
-        </xs:element>
-        <xs:element name="preprocess" minOccurs="0" maxOccurs="1">
-          <xs:complexType>
-            <xs:sequence>
-              <xs:element name="stream" type="aec:streamPreprocessType" minOccurs="0" maxOccurs="unbounded"/>
-            </xs:sequence>
-          </xs:complexType>
-        </xs:element>
-      </xs:sequence>
-      <xs:attribute name="version" type="aec:versionType" use="required"/>
-    </xs:complexType>
-
-    <!-- Keys and references -->
-    <xs:key name="libraryName">
-      <xs:selector xpath="aec:libraries/aec:library"/>
-      <xs:field xpath="@name"/>
-    </xs:key>
-    <xs:keyref name="libraryNameRef1" refer="aec:libraryName">
-      <xs:selector xpath="aec:effects/aec:effect"/>
-      <xs:field xpath="@library"/>
-    </xs:keyref>
-    <xs:keyref name="libraryNameRef2" refer="aec:libraryName">
-      <xs:selector xpath="aec:effects/aec:effect/aec:libsw"/>
-      <xs:field xpath="@library"/>
-    </xs:keyref>
-    <xs:keyref name="libraryNameRef3" refer="aec:libraryName">
-      <xs:selector xpath="aec:effects/aec:effect/aec:libhw"/>
-      <xs:field xpath="@library"/>
-    </xs:keyref>
-    <xs:key name="effectName">
-      <xs:selector xpath="aec:effects/aec:effect"/>
-      <xs:field xpath="@name"/>
-    </xs:key>
-    <xs:keyref name="effectNamePreRef" refer="aec:effectName">
-      <xs:selector xpath="aec:preprocess/aec:stream/aec:apply"/>
-      <xs:field xpath="@effect"/>
-    </xs:keyref>
-    <xs:keyref name="effectNamePostRef" refer="aec:effectName">
-      <xs:selector xpath="aec:postprocess/aec:stream/aec:apply"/>
-      <xs:field xpath="@effect"/>
-    </xs:keyref>
-  </xs:element>
-</xs:schema>
diff --git a/bluetooth/1.0/default/bluetooth_address.cc b/bluetooth/1.0/default/bluetooth_address.cc
index 656d78d..65dc6a6 100644
--- a/bluetooth/1.0/default/bluetooth_address.cc
+++ b/bluetooth/1.0/default/bluetooth_address.cc
@@ -16,8 +16,8 @@
 
 #include "bluetooth_address.h"
 
-#include <android-base/logging.h>
 #include <cutils/properties.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <utils/Log.h>
 
@@ -54,19 +54,25 @@
 
     addr_fd = open(property, O_RDONLY);
     if (addr_fd != -1) {
-      int bytes_read = read(addr_fd, property, kStringLength);
-      CHECK(bytes_read == kStringLength);
+      char address[kStringLength + 1] = {0};
+      int bytes_read = read(addr_fd, address, kStringLength);
+      if (bytes_read == -1) {
+        ALOGE("%s: Error reading address from %s: %s", __func__, property,
+              strerror(errno));
+      }
       close(addr_fd);
 
       // Null terminate the string.
-      property[kStringLength] = '\0';
+      address[kStringLength] = '\0';
 
       // If the address is not all zeros, then use it.
       const uint8_t zero_bdaddr[kBytes] = {0, 0, 0, 0, 0, 0};
-      if ((string_to_bytes(property, local_addr)) &&
+      if ((string_to_bytes(address, local_addr)) &&
           (memcmp(local_addr, zero_bdaddr, kBytes) != 0)) {
         valid_bda = true;
-        ALOGD("%s: Got Factory BDA %s", __func__, property);
+        ALOGD("%s: Got Factory BDA %s", __func__, address);
+      } else {
+        ALOGE("%s: Got Invalid BDA '%s' from %s", __func__, address, property);
       }
     }
   }
diff --git a/bluetooth/1.0/default/h4_protocol.cc b/bluetooth/1.0/default/h4_protocol.cc
index 8f24b5e..2008b00 100644
--- a/bluetooth/1.0/default/h4_protocol.cc
+++ b/bluetooth/1.0/default/h4_protocol.cc
@@ -17,9 +17,11 @@
 #include "h4_protocol.h"
 
 #define LOG_TAG "android.hardware.bluetooth-hci-h4"
-#include <android-base/logging.h>
-#include <assert.h>
+
+#include <errno.h>
 #include <fcntl.h>
+#include <log/log.h>
+#include <sys/uio.h>
 
 namespace android {
 namespace hardware {
@@ -27,11 +29,20 @@
 namespace hci {
 
 size_t H4Protocol::Send(uint8_t type, const uint8_t* data, size_t length) {
-  int rv = WriteSafely(uart_fd_, &type, sizeof(type));
-  if (rv == sizeof(type)) {
-    rv = WriteSafely(uart_fd_, data, length);
+  struct iovec iov[] = {{&type, sizeof(type)},
+                        {const_cast<uint8_t*>(data), length}};
+  ssize_t ret = 0;
+  do {
+    ret = TEMP_FAILURE_RETRY(writev(uart_fd_, iov, sizeof(iov) / sizeof(iov[0])));
+  } while (-1 == ret && EAGAIN == errno);
+
+  if (ret == -1) {
+    ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
+  } else if (ret < static_cast<ssize_t>(length + 1)) {
+    ALOGE("%s: %d / %d bytes written - something went wrong...", __func__,
+          static_cast<int>(ret), static_cast<int>(length + 1));
   }
-  return rv;
+  return ret;
 }
 
 void H4Protocol::OnPacketReady() {
@@ -45,10 +56,9 @@
     case HCI_PACKET_TYPE_SCO_DATA:
       sco_cb_(hci_packetizer_.GetPacket());
       break;
-    default: {
-      bool bad_packet_type = true;
-      CHECK(!bad_packet_type);
-    }
+    default:
+      LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__,
+                       static_cast<int>(hci_packet_type_));
   }
   // Get ready for the next type byte.
   hci_packet_type_ = HCI_PACKET_TYPE_UNKNOWN;
@@ -57,8 +67,19 @@
 void H4Protocol::OnDataReady(int fd) {
   if (hci_packet_type_ == HCI_PACKET_TYPE_UNKNOWN) {
     uint8_t buffer[1] = {0};
-    size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
-    CHECK(bytes_read == 1);
+    ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
+    if (bytes_read != 1) {
+      if (bytes_read == 0) {
+        LOG_ALWAYS_FATAL("%s: Unexpected EOF reading the packet type!",
+                         __func__);
+      } else if (bytes_read < 0) {
+        LOG_ALWAYS_FATAL("%s: Read packet type error: %s", __func__,
+                         strerror(errno));
+      } else {
+        LOG_ALWAYS_FATAL("%s: More bytes read than expected (%u)!", __func__,
+                         static_cast<unsigned int>(bytes_read));
+      }
+    }
     hci_packet_type_ = static_cast<HciPacketType>(buffer[0]);
   } else {
     hci_packetizer_.OnDataReady(fd, hci_packet_type_);
diff --git a/bluetooth/1.0/default/hci_packetizer.cc b/bluetooth/1.0/default/hci_packetizer.cc
index 9549858..2da1254 100644
--- a/bluetooth/1.0/default/hci_packetizer.cc
+++ b/bluetooth/1.0/default/hci_packetizer.cc
@@ -17,11 +17,11 @@
 #include "hci_packetizer.h"
 
 #define LOG_TAG "android.hardware.bluetooth.hci_packetizer"
-#include <android-base/logging.h>
-#include <utils/Log.h>
 
 #include <dlfcn.h>
+#include <errno.h>
 #include <fcntl.h>
+#include <utils/Log.h>
 
 namespace {
 
@@ -45,15 +45,22 @@
 namespace bluetooth {
 namespace hci {
 
-const hidl_vec<uint8_t>& HciPacketizer::GetPacket() const { return packet_; }
+const hidl_vec<uint8_t>& HciPacketizer::GetPacket() const {
+  return packet_;
+}
 
 void HciPacketizer::OnDataReady(int fd, HciPacketType packet_type) {
   switch (state_) {
     case HCI_PREAMBLE: {
-      size_t bytes_read = TEMP_FAILURE_RETRY(
+      ssize_t bytes_read = TEMP_FAILURE_RETRY(
           read(fd, preamble_ + bytes_read_,
                preamble_size_for_type[packet_type] - bytes_read_));
-      CHECK(bytes_read > 0);
+      if (bytes_read <= 0) {
+        LOG_ALWAYS_FATAL_IF((bytes_read == 0),
+                            "%s: Unexpected EOF reading the header!", __func__);
+        LOG_ALWAYS_FATAL("%s: Read header error: %s", __func__,
+                         strerror(errno));
+      }
       bytes_read_ += bytes_read;
       if (bytes_read_ == preamble_size_for_type[packet_type]) {
         size_t packet_length =
@@ -68,11 +75,17 @@
     }
 
     case HCI_PAYLOAD: {
-      size_t bytes_read = TEMP_FAILURE_RETRY(read(
+      ssize_t bytes_read = TEMP_FAILURE_RETRY(read(
           fd,
           packet_.data() + preamble_size_for_type[packet_type] + bytes_read_,
           bytes_remaining_));
-      CHECK(bytes_read > 0);
+      if (bytes_read <= 0) {
+        LOG_ALWAYS_FATAL_IF((bytes_read == 0),
+                            "%s: Unexpected EOF reading the payload!",
+                            __func__);
+        LOG_ALWAYS_FATAL("%s: Read payload error: %s", __func__,
+                         strerror(errno));
+      }
       bytes_remaining_ -= bytes_read;
       bytes_read_ += bytes_read;
       if (bytes_remaining_ == 0) {
diff --git a/bluetooth/1.0/default/mct_protocol.cc b/bluetooth/1.0/default/mct_protocol.cc
index 813cebd..2a59187 100644
--- a/bluetooth/1.0/default/mct_protocol.cc
+++ b/bluetooth/1.0/default/mct_protocol.cc
@@ -19,7 +19,6 @@
 #include <assert.h>
 
 #define LOG_TAG "android.hardware.bluetooth-hci-mct"
-#include <android-base/logging.h>
 #include <utils/Log.h>
 
 #include <fcntl.h>
@@ -45,7 +44,7 @@
     return WriteSafely(uart_fds_[CH_CMD], data, length);
   if (type == HCI_PACKET_TYPE_ACL_DATA)
     return WriteSafely(uart_fds_[CH_ACL_OUT], data, length);
-  CHECK(type == HCI_PACKET_TYPE_COMMAND || type == HCI_PACKET_TYPE_ACL_DATA);
+  LOG_ALWAYS_FATAL("%s: Unimplemented packet type = %d", __func__, type);
   return 0;
 }
 
diff --git a/bluetooth/1.0/default/test/bluetooth_address_test.cc b/bluetooth/1.0/default/test/bluetooth_address_test.cc
index adcd9c1..e60729e 100644
--- a/bluetooth/1.0/default/test/bluetooth_address_test.cc
+++ b/bluetooth/1.0/default/test/bluetooth_address_test.cc
@@ -15,6 +15,7 @@
 //
 
 #include <cutils/properties.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <gtest/gtest.h>
 
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index a291e14..ffc283e 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -17,7 +17,6 @@
 #include "vendor_interface.h"
 
 #define LOG_TAG "android.hardware.bluetooth@1.0-impl"
-#include <android-base/logging.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 
@@ -163,14 +162,16 @@
     InitializeCompleteCallback initialize_complete_cb,
     PacketReadCallback event_cb, PacketReadCallback acl_cb,
     PacketReadCallback sco_cb) {
-  CHECK(!g_vendor_interface);
+  LOG_ALWAYS_FATAL_IF(g_vendor_interface, "%s: No previous Shutdown()?",
+                      __func__);
   g_vendor_interface = new VendorInterface();
   return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb,
                                   sco_cb);
 }
 
 void VendorInterface::Shutdown() {
-  CHECK(g_vendor_interface);
+  LOG_ALWAYS_FATAL_IF(!g_vendor_interface, "%s: No Vendor interface!",
+                      __func__);
   g_vendor_interface->Close();
   delete g_vendor_interface;
   g_vendor_interface = nullptr;
@@ -204,7 +205,9 @@
   // Get the local BD address
 
   uint8_t local_bda[BluetoothAddress::kBytes];
-  CHECK(BluetoothAddress::get_local_address(local_bda));
+  if (!BluetoothAddress::get_local_address(local_bda)) {
+    LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__);
+  }
   int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
   if (status) {
     ALOGE("%s unable to initialize vendor library: %d", __func__, status);
diff --git a/camera/common/1.0/default/Android.bp b/camera/common/1.0/default/Android.bp
index 03a71fa..6209cb8 100644
--- a/camera/common/1.0/default/Android.bp
+++ b/camera/common/1.0/default/Android.bp
@@ -1,10 +1,11 @@
 cc_library_static {
     name: "android.hardware.camera.common@1.0-helper",
-    vendor: true,
+    vendor_available: true,
     defaults: ["hidl_defaults"],
     srcs: [
         "CameraModule.cpp",
         "CameraMetadata.cpp",
+        "CameraParameters.cpp",
         "VendorTagDescriptor.cpp",
         "HandleImporter.cpp"],
     cflags: [
diff --git a/camera/provider/2.4/vts/functional/CameraParameters.cpp b/camera/common/1.0/default/CameraParameters.cpp
similarity index 98%
rename from camera/provider/2.4/vts/functional/CameraParameters.cpp
rename to camera/common/1.0/default/CameraParameters.cpp
index 97b263b..d224483 100644
--- a/camera/provider/2.4/vts/functional/CameraParameters.cpp
+++ b/camera/common/1.0/default/CameraParameters.cpp
@@ -24,6 +24,12 @@
 #include <system/graphics.h>
 
 namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace V1_0 {
+namespace helper {
+
 // Parameter keys to communicate between camera application and driver.
 const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
 const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
@@ -534,4 +540,9 @@
     return mMap.isEmpty();
 }
 
+};
+};
+};
+};
+};
 }; // namespace android
diff --git a/camera/provider/2.4/vts/functional/CameraParameters.h b/camera/common/1.0/default/include/CameraParameters.h
similarity index 99%
rename from camera/provider/2.4/vts/functional/CameraParameters.h
rename to camera/common/1.0/default/include/CameraParameters.h
index ba33ffe..e4ff6f2 100644
--- a/camera/provider/2.4/vts/functional/CameraParameters.h
+++ b/camera/common/1.0/default/include/CameraParameters.h
@@ -21,6 +21,11 @@
 #include <utils/String8.h>
 
 namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace V1_0 {
+namespace helper {
 
 struct Size {
     int width;
@@ -694,6 +699,11 @@
     DefaultKeyedVector<String8,String8>    mMap;
 };
 
-}; // namespace android
+};
+};
+};
+};
+};
+}; // namespace
 
 #endif
diff --git a/camera/device/1.0/default/CameraDevice.cpp b/camera/device/1.0/default/CameraDevice.cpp
index 6f4e70f..c53c0d8 100644
--- a/camera/device/1.0/default/CameraDevice.cpp
+++ b/camera/device/1.0/default/CameraDevice.cpp
@@ -116,7 +116,7 @@
     Mutex::Autolock _l(mLock);
     if (mDevice != nullptr) {
         ALOGW("%s: camera %s is deleted while open", __FUNCTION__, mCameraId.c_str());
-        close();
+        closeLocked();
     }
     mHalPreviewWindow.cleanUpCirculatingBuffers();
 }
@@ -130,7 +130,7 @@
     }
     if (!connected) {
         ALOGW("%s: camera %s is disconneted. Closing", __FUNCTION__, mCameraId.c_str());
-        close();
+        closeLocked();
     }
     return;
 }
@@ -982,8 +982,13 @@
 }
 
 Return<void> CameraDevice::close() {
-    ALOGI("Closing camera %s", mCameraId.c_str());
     Mutex::Autolock _l(mLock);
+    closeLocked();
+    return Void();
+}
+
+void CameraDevice::closeLocked() {
+    ALOGI("Closing camera %s", mCameraId.c_str());
     if(mDevice) {
         int rc = mDevice->common.close(&mDevice->common);
         if (rc != OK) {
@@ -991,7 +996,6 @@
         }
         mDevice = nullptr;
     }
-    return Void();
 }
 
 }  // namespace implementation
diff --git a/camera/device/1.0/default/CameraDevice_1_0.h b/camera/device/1.0/default/CameraDevice_1_0.h
index 0e5a49b..c078596 100644
--- a/camera/device/1.0/default/CameraDevice_1_0.h
+++ b/camera/device/1.0/default/CameraDevice_1_0.h
@@ -222,6 +222,7 @@
     static status_t getStatusT(const Status& s);
 
     Status initStatus() const;
+    void closeLocked();
 };
 
 }  // namespace implementation
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 85312c1..439fe3d 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -17,8 +17,7 @@
 cc_test {
     name: "VtsHalCameraProviderV2_4TargetTest",
     defaults: ["hidl_defaults"],
-    srcs: ["VtsHalCameraProviderV2_4TargetTest.cpp",
-           "CameraParameters.cpp" ],
+    srcs: ["VtsHalCameraProviderV2_4TargetTest.cpp"],
     shared_libs: [
         "liblog",
         "libhidlbase",
@@ -31,9 +30,14 @@
         "libcamera_metadata",
         "libbinder",
         "libgui",
-        "libui"
+        "libui",
+        "libfmq",
     ],
-    static_libs: ["VtsHalHidlTargetTestBase", "libgrallocusage"],
+    static_libs: [
+        "VtsHalHidlTargetTestBase",
+        "libgrallocusage",
+        "android.hardware.camera.common@1.0-helper",
+    ],
     cflags: [
         "-O0",
         "-g",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 8695e4e..2ae4853 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -15,29 +15,34 @@
  */
 
 #define LOG_TAG "camera_hidl_hal_test"
-#include <VtsHalHidlTargetTestBase.h>
+
+#include <chrono>
+#include <mutex>
+#include <regex>
+#include <unordered_map>
+#include <condition_variable>
+
+#include <inttypes.h>
+
 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
-#include <android/log.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
+#include <CameraMetadata.h>
+#include <CameraParameters.h>
+#include <fmq/MessageQueue.h>
 #include <grallocusage/GrallocUsageConversion.h>
 #include <gui/BufferItemConsumer.h>
 #include <gui/BufferQueue.h>
 #include <gui/Surface.h>
 #include <hardware/gralloc.h>
 #include <hardware/gralloc1.h>
-#include <inttypes.h>
 #include <system/camera.h>
+#include <system/camera_metadata.h>
 #include <ui/GraphicBuffer.h>
-#include <utils/Errors.h>
-#include <chrono>
-#include <condition_variable>
-#include <mutex>
-#include <regex>
-#include <unordered_map>
-#include "CameraParameters.h"
-#include "system/camera_metadata.h"
+
+#include <VtsHalHidlTargetTestBase.h>
 
 using ::android::hardware::Return;
 using ::android::hardware::Void;
@@ -52,13 +57,14 @@
 using ::android::BufferQueue;
 using ::android::BufferItemConsumer;
 using ::android::Surface;
-using ::android::CameraParameters;
 using ::android::hardware::graphics::common::V1_0::BufferUsage;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
 using ::android::hardware::camera::common::V1_0::Status;
 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
 using ::android::hardware::camera::common::V1_0::TorchMode;
 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
+using ::android::hardware::camera::common::V1_0::helper::CameraParameters;
+using ::android::hardware::camera::common::V1_0::helper::Size;
 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
 using ::android::hardware::camera::device::V3_2::ICameraDevice;
@@ -89,8 +95,13 @@
 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
 using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
 using ::android::hardware::camera::device::V1_0::HandleTimestampMessage;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::kSynchronizedReadWrite;
+using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using ::android::hidl::manager::V1_0::IServiceManager;
 
-const char kCameraLegacyServiceName[] = "legacy/0";
+const char kCameraPassthroughServiceName[] = "legacy/0";
+const char *kProviderFQName = "android.hardware.camera.provider@2.4::ICameraProvider";
 const uint32_t kMaxPreviewWidth = 1920;
 const uint32_t kMaxPreviewHeight = 1080;
 const uint32_t kMaxVideoWidth = 4096;
@@ -114,21 +125,25 @@
 
 namespace {
     // "device@<version>/legacy/<id>"
-    const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/legacy/(.+)";
+    const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
     const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
     const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
     const char *kHAL3_2 = "3.2";
     const char *kHAL1_0 = "1.0";
 
-    bool matchDeviceName(const hidl_string& deviceName, std::smatch& sm) {
-        std::regex e(kDeviceNameRE);
+    bool matchDeviceName(const hidl_string& deviceName,
+            const hidl_string &providerType, std::smatch& sm) {
+        ::android::String8 pattern;
+        pattern.appendFormat(kDeviceNameRE, providerType.c_str());
+        std::regex e(pattern.string());
         std::string deviceNameStd(deviceName.c_str());
         return std::regex_match(deviceNameStd, sm, e);
     }
 
-    int getCameraDeviceVersion(const hidl_string& deviceName) {
+    int getCameraDeviceVersion(const hidl_string& deviceName,
+            const hidl_string &providerType) {
         std::smatch sm;
-        bool match = matchDeviceName(deviceName, sm);
+        bool match = matchDeviceName(deviceName, providerType, sm);
         if (!match) {
             return -1;
         }
@@ -142,6 +157,45 @@
         return 0;
     }
 
+    bool parseProviderName(const std::string& name, std::string *type /*out*/,
+            uint32_t *id /*out*/) {
+        if (!type || !id) {
+            ADD_FAILURE();
+            return false;
+        }
+
+        std::string::size_type slashIdx = name.find('/');
+        if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
+            ADD_FAILURE() << "Provider name does not have / separator between type"
+                    "and id";
+            return false;
+        }
+
+        std::string typeVal = name.substr(0, slashIdx);
+
+        char *endPtr;
+        errno = 0;
+        long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
+        if (errno != 0) {
+            ADD_FAILURE() << "cannot parse provider id as an integer:" <<
+                    name.c_str() << strerror(errno) << errno;
+            return false;
+        }
+        if (endPtr != name.c_str() + name.size()) {
+            ADD_FAILURE() << "provider id has unexpected length " << name.c_str();
+            return false;
+        }
+        if (idVal < 0) {
+            ADD_FAILURE() << "id is negative: " << name.c_str() << idVal;
+            return false;
+        }
+
+        *type = typeVal;
+        *id = static_cast<uint32_t>(idVal);
+
+        return true;
+    }
+
     Status mapToStatus(::android::status_t s)  {
         switch(s) {
             case ::android::OK:
@@ -176,7 +230,7 @@
     virtual void SetUp() override;
     virtual void TearDown() override;
 
-    sp<ICameraProvider> mProvider;
+    std::unordered_map<std::string, sp<ICameraProvider> > mProviders;
 
 private:
     CameraHidlEnvironment() {}
@@ -185,9 +239,40 @@
 };
 
 void CameraHidlEnvironment::SetUp() {
-    mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(kCameraLegacyServiceName);
-    ALOGI_IF(mProvider, "provider is not nullptr, %p", mProvider.get());
-    ASSERT_NE(mProvider, nullptr);
+    sp<IServiceManager> manager = IServiceManager::getService();
+    ASSERT_NE(manager, nullptr);
+
+    manager->listByInterface(kProviderFQName,
+                             [this](const hidl_vec<hidl_string> &registered) {
+        std::string name;
+        uint32_t id;
+        sp<ICameraProvider> provider = nullptr;
+        for (size_t i = 0; i < registered.size(); i++) {
+            ASSERT_TRUE(parseProviderName(registered[i],
+                    &name /*out*/, &id /*out*/));
+            provider = ICameraProvider::tryGetService(registered[i]);
+            ALOGI_IF(provider, "provider is not nullptr, %p", provider.get());
+            if (nullptr != provider.get()) {
+                mProviders.emplace(name, provider);
+            }
+        }
+    });
+
+    std::string legacyName;
+    uint32_t legacyId;
+    ASSERT_TRUE(parseProviderName(kCameraPassthroughServiceName,
+            &legacyName /*out*/, &legacyId /*out*/));
+    auto legacyIt = mProviders.find(legacyName);
+    //Add any legacy passthrough implementations
+    if (legacyIt == mProviders.end()) {
+        sp<ICameraProvider> provider = ICameraProvider::tryGetService(
+                kCameraPassthroughServiceName);
+        if (nullptr != provider.get()) {
+            mProviders.emplace(legacyName, provider);
+        }
+    }
+
+    ASSERT_FALSE(mProviders.empty());
 }
 
 void CameraHidlEnvironment::TearDown() {
@@ -251,9 +336,7 @@
 
             size_t result = 1;
             result = 31 * result + buf->numFds;
-            result = 31 * result + buf->numInts;
-            int length = buf->numFds + buf->numInts;
-            for (int i = 0; i < length; i++) {
+            for (int i = 0; i < buf->numFds; i++) {
                 result = 31 * result + buf->data[i];
             }
             return result;
@@ -263,10 +346,8 @@
     struct BufferComparator {
         bool operator()(const buffer_handle_t& buf1,
                 const buffer_handle_t& buf2) const {
-            if ((buf1->numFds == buf2->numFds) &&
-                    (buf1->numInts == buf2->numInts)) {
-                int length = buf1->numFds + buf1->numInts;
-                for (int i = 0; i < length; i++) {
+            if (buf1->numFds == buf2->numFds) {
+                for (int i = 0; i < buf1->numFds; i++) {
                     if (buf1->data[i] != buf2->data[i]) {
                         return false;
                     }
@@ -443,7 +524,7 @@
     virtual void SetUp() override {}
     virtual void TearDown() override {}
 
-    hidl_vec<hidl_string> getCameraDeviceNames();
+    hidl_vec<hidl_string> getCameraDeviceNames(sp<ICameraProvider> provider);
 
     struct EmptyDeviceCb : public ICameraDeviceCallback {
         virtual Return<void> processCaptureResult(const hidl_vec<CaptureResult>& /*results*/) override {
@@ -519,7 +600,7 @@
         CameraHidlTest *mParent;               // Parent object
     };
 
-    void openCameraDevice(const std::string &name,const CameraHidlEnvironment* env,
+    void openCameraDevice(const std::string &name, sp<ICameraProvider> provider,
             sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
     void setupPreviewWindow(
             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
@@ -542,15 +623,17 @@
     void waitForFrameLocked(DataCallbackMsg msgFrame,
             std::unique_lock<std::mutex> &l);
     void openEmptyDeviceSession(const std::string &name,
-            const CameraHidlEnvironment* env,
+            sp<ICameraProvider> provider,
             sp<ICameraDeviceSession> *session /*out*/,
             camera_metadata_t **staticMeta /*out*/);
     void configurePreviewStream(const std::string &name,
-            const CameraHidlEnvironment* env,
+            sp<ICameraProvider> provider,
             const AvailableStream *previewThreshold,
             sp<ICameraDeviceSession> *session /*out*/,
             Stream *previewStream /*out*/,
-            HalStreamConfiguration *halStreamConfig /*out*/);
+            HalStreamConfiguration *halStreamConfig /*out*/,
+            bool *supportsPartialResults /*out*/,
+            uint32_t *partialResultCount /*out*/);
     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
             std::vector<AvailableStream> &outputStreams,
             const AvailableStream *threshold = nullptr);
@@ -564,14 +647,78 @@
             const std::vector<AvailableStream> &streamSizes,
             int32_t format, AvailableStream &result);
     static Status isAutoFocusModeAvailable(
-            ::android::CameraParameters &cameraParams, const char *mode) ;
+            CameraParameters &cameraParams, const char *mode) ;
 
 protected:
+
+    // In-flight queue for tracking completion of capture requests.
+    struct InFlightRequest {
+        // Set by notify() SHUTTER call.
+        nsecs_t shutterTimestamp;
+
+        bool errorCodeValid;
+        ErrorCode errorCode;
+
+        //Is partial result supported
+        bool usePartialResult;
+
+        //Partial result count expected
+        uint32_t numPartialResults;
+
+        // Message queue
+        std::shared_ptr<ResultMetadataQueue> resultQueue;
+
+        // Set by process_capture_result call with valid metadata
+        bool haveResultMetadata;
+
+        // Decremented by calls to process_capture_result with valid output
+        // and input buffers
+        ssize_t numBuffersLeft;
+
+         // A 64bit integer to index the frame number associated with this result.
+        int64_t frameNumber;
+
+         // The partial result count (index) for this capture result.
+        int32_t partialResultCount;
+
+        // For buffer drop errors, the stream ID for the stream that lost a buffer.
+        // Otherwise -1.
+        int32_t errorStreamId;
+
+        // If this request has any input buffer
+        bool hasInputBuffer;
+
+        // Result metadata
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult;
+
+        // Buffers are added by process_capture_result when output buffers
+        // return from HAL but framework.
+        ::android::Vector<StreamBuffer> resultOutputBuffers;
+
+        InFlightRequest(ssize_t numBuffers, bool hasInput,
+                bool partialResults, uint32_t partialCount,
+                std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
+                shutterTimestamp(0),
+                errorCodeValid(false),
+                errorCode(ErrorCode::ERROR_BUFFER),
+                usePartialResult(partialResults),
+                numPartialResults(partialCount),
+                resultQueue(queue),
+                haveResultMetadata(false),
+                numBuffersLeft(numBuffers),
+                frameNumber(0),
+                partialResultCount(0),
+                errorStreamId(-1),
+                hasInputBuffer(hasInput) {}
+    };
+
+    // Map from frame number to the in-flight request state
+    typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap;
+
     std::mutex mLock;                          // Synchronize access to member variables
     std::condition_variable mResultCondition;  // Condition variable for incoming results
-    uint32_t mResultFrameNumber;               // Expected result frame number
-    std::vector<StreamBuffer> mResultBuffers;  // Holds stream buffers from capture result
-    std::vector<ErrorMsg> mErrors;             // Holds incoming error notifications
+    InFlightMap mInflightMap;                  // Map of all inflight requests
+
     DataCallbackMsg mDataMessageTypeReceived;  // Most recent message type received through data callbacks
     uint32_t mVideoBufferIndex;                // Buffer index of the most recent video buffer
     uint32_t mVideoData;                       // Buffer data of the most recent video buffer
@@ -694,53 +841,180 @@
         return Void();
     }
 
+    bool notify = false;
     std::unique_lock<std::mutex> l(mParent->mLock);
-    const CaptureResult& result = results[0];
+    for (size_t i = 0 ; i < results.size(); i++) {
+        uint32_t frameNumber = results[i].frameNumber;
 
-    if(mParent->mResultFrameNumber != result.frameNumber) {
-        ALOGE("%s: Unexpected frame number! Expected: %u received: %u",
-              __func__, mParent->mResultFrameNumber, result.frameNumber);
-        ADD_FAILURE();
+        if ((results[i].result.size() == 0) &&
+                (results[i].outputBuffers.size() == 0) &&
+                (results[i].inputBuffer.buffer == nullptr) &&
+                (results[i].fmqResultSize == 0)) {
+            ALOGE("%s: No result data provided by HAL for frame %d result count: %d",
+                  __func__, frameNumber, (int) results[i].fmqResultSize);
+            ADD_FAILURE();
+            break;
+        }
+
+        ssize_t idx = mParent->mInflightMap.indexOfKey(frameNumber);
+        if (::android::NAME_NOT_FOUND == idx) {
+            ALOGE("%s: Unexpected frame number! received: %u",
+                  __func__, frameNumber);
+            ADD_FAILURE();
+            break;
+        }
+
+        bool isPartialResult = false;
+        bool hasInputBufferInRequest = false;
+        InFlightRequest *request = mParent->mInflightMap.editValueAt(idx);
+        ::android::hardware::camera::device::V3_2::CameraMetadata resultMetadata;
+        size_t resultSize = 0;
+        if (results[i].fmqResultSize > 0) {
+            resultMetadata.resize(results[i].fmqResultSize);
+            if (request->resultQueue == nullptr) {
+                ADD_FAILURE();
+                break;
+            }
+            if (!request->resultQueue->read(resultMetadata.data(),
+                    results[i].fmqResultSize)) {
+                ALOGE("%s: Frame %d: Cannot read camera metadata from fmq,"
+                        "size = %" PRIu64, __func__, frameNumber,
+                        results[i].fmqResultSize);
+                ADD_FAILURE();
+                break;
+            }
+            resultSize = resultMetadata.size();
+        } else if (results[i].result.size() > 0) {
+            resultMetadata.setToExternal(const_cast<uint8_t *>(
+                    results[i].result.data()), results[i].result.size());
+            resultSize = resultMetadata.size();
+        }
+
+        if (!request->usePartialResult && (resultSize > 0) &&
+                (results[i].partialResult != 1)) {
+            ALOGE("%s: Result is malformed for frame %d: partial_result %u "
+                    "must be 1  if partial result is not supported", __func__,
+                    frameNumber, results[i].partialResult);
+            ADD_FAILURE();
+            break;
+        }
+
+        if (results[i].partialResult != 0) {
+            request->partialResultCount = results[i].partialResult;
+        }
+
+        // Check if this result carries only partial metadata
+        if (request->usePartialResult && (resultSize > 0)) {
+            if ((results[i].partialResult > request->numPartialResults) ||
+                    (results[i].partialResult < 1)) {
+                ALOGE("%s: Result is malformed for frame %d: partial_result %u"
+                        " must be  in the range of [1, %d] when metadata is "
+                        "included in the result", __func__, frameNumber,
+                        results[i].partialResult, request->numPartialResults);
+                ADD_FAILURE();
+                break;
+            }
+            request->collectedResult.append(
+                    reinterpret_cast<const camera_metadata_t*>(
+                            resultMetadata.data()));
+
+            isPartialResult =
+                    (results[i].partialResult < request->numPartialResults);
+        }
+
+        hasInputBufferInRequest = request->hasInputBuffer;
+
+        // Did we get the (final) result metadata for this capture?
+        if ((resultSize > 0) && !isPartialResult) {
+            if (request->haveResultMetadata) {
+                ALOGE("%s: Called multiple times with metadata for frame %d",
+                      __func__, frameNumber);
+                ADD_FAILURE();
+                break;
+            }
+            request->haveResultMetadata = true;
+            request->collectedResult.sort();
+        }
+
+        uint32_t numBuffersReturned = results[i].outputBuffers.size();
+        if (results[i].inputBuffer.buffer != nullptr) {
+            if (hasInputBufferInRequest) {
+                numBuffersReturned += 1;
+            } else {
+                ALOGW("%s: Input buffer should be NULL if there is no input"
+                        " buffer sent in the request", __func__);
+            }
+        }
+        request->numBuffersLeft -= numBuffersReturned;
+        if (request->numBuffersLeft < 0) {
+            ALOGE("%s: Too many buffers returned for frame %d", __func__,
+                    frameNumber);
+            ADD_FAILURE();
+            break;
+        }
+
+        request->resultOutputBuffers.appendArray(results[i].outputBuffers.data(),
+                results[i].outputBuffers.size());
+        // If shutter event is received notify the pending threads.
+        if (request->shutterTimestamp != 0) {
+            notify = true;
+        }
     }
 
-    size_t resultLength = result.outputBuffers.size();
-    for (size_t i = 0; i < resultLength; i++) {
-        mParent->mResultBuffers.push_back(result.outputBuffers[i]);
-    }
-
-    // TODO(epeev): Handle partial results in case client supports them and
-    //              verify the result against request settings.
-
     l.unlock();
-    mParent->mResultCondition.notify_one();
+    if (notify) {
+        mParent->mResultCondition.notify_one();
+    }
 
     return Void();
 }
 
 Return<void> CameraHidlTest::DeviceCb::notify(
         const hidl_vec<NotifyMsg>& messages) {
-    const NotifyMsg& message = messages[0];
+    std::lock_guard<std::mutex> l(mParent->mLock);
 
-    if (MsgType::ERROR == message.type) {
-        {
-            std::lock_guard<std::mutex> l(mParent->mLock);
-            mParent->mErrors.push_back(message.msg.error);
+    for (size_t i = 0; i < messages.size(); i++) {
+        ssize_t idx = mParent->mInflightMap.indexOfKey(
+                messages[i].msg.shutter.frameNumber);
+        if (::android::NAME_NOT_FOUND == idx) {
+            ALOGE("%s: Unexpected frame number! received: %u",
+                  __func__, messages[i].msg.shutter.frameNumber);
+            ADD_FAILURE();
+            break;
         }
+        InFlightRequest *r = mParent->mInflightMap.editValueAt(idx);
 
-        if ((ErrorCode::ERROR_REQUEST == message.msg.error.errorCode)
-                || (ErrorCode::ERROR_BUFFER == message.msg.error.errorCode)) {
-            mParent->mResultCondition.notify_one();
+        switch(messages[i].type) {
+            case MsgType::ERROR:
+                if (ErrorCode::ERROR_DEVICE == messages[i].msg.error.errorCode) {
+                    ALOGE("%s: Camera reported serious device error",
+                          __func__);
+                    ADD_FAILURE();
+                } else {
+                    r->errorCodeValid = true;
+                    r->errorCode = messages[i].msg.error.errorCode;
+                    r->errorStreamId = messages[i].msg.error.errorStreamId;
+                }
+                break;
+            case MsgType::SHUTTER:
+                r->shutterTimestamp = messages[i].msg.shutter.timestamp;
+                break;
+            default:
+                ALOGE("%s: Unsupported notify message %d", __func__,
+                      messages[i].type);
+                ADD_FAILURE();
+                break;
         }
     }
 
+    mParent->mResultCondition.notify_one();
     return Void();
 }
 
-hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames() {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames(sp<ICameraProvider> provider) {
     hidl_vec<hidl_string> cameraDeviceNames;
     Return<void> ret;
-    ret = env->mProvider->getCameraIdList(
+    ret = provider->getCameraIdList(
         [&](auto status, const auto& idList) {
             ALOGI("getCameraIdList returns status:%d", (int)status);
             for (size_t i = 0; i < idList.size(); i++) {
@@ -758,58 +1032,63 @@
 // Test if ICameraProvider::isTorchModeSupported returns Status::OK
 TEST_F(CameraHidlTest, isTorchModeSupported) {
     Return<void> ret;
-    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
-        [&](auto status, bool support) {
-            ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
-                    (int)status, support);
-            ASSERT_EQ(Status::OK, status);
-        });
-    ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        ret = provider.second->isSetTorchModeSupported(
+            [&](auto status, bool support) {
+                ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
+                        (int)status, support);
+                ASSERT_EQ(Status::OK, status);
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 // TODO: consider removing this test if getCameraDeviceNames() has the same coverage
 TEST_F(CameraHidlTest, getCameraIdList) {
     Return<void> ret;
-    ret = CameraHidlEnvironment::Instance()->mProvider->getCameraIdList(
-        [&](auto status, const auto& idList) {
-            ALOGI("getCameraIdList returns status:%d", (int)status);
-            for (size_t i = 0; i < idList.size(); i++) {
-                ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
-            }
-            ASSERT_EQ(Status::OK, status);
-            // This is true for internal camera provider.
-            // Not necessary hold for external cameras providers
-            ASSERT_GT(idList.size(), 0u);
-        });
-    ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        ret = provider.second->getCameraIdList(
+            [&](auto status, const auto& idList) {
+                ALOGI("getCameraIdList returns status:%d", (int)status);
+                for (size_t i = 0; i < idList.size(); i++) {
+                    ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
+                }
+                ASSERT_EQ(Status::OK, status);
+                // This is true for internal camera provider.
+                // Not necessary hold for external cameras providers
+                ASSERT_GT(idList.size(), 0u);
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 // Test if ICameraProvider::getVendorTags returns Status::OK
 TEST_F(CameraHidlTest, getVendorTags) {
     Return<void> ret;
-    ret = CameraHidlEnvironment::Instance()->mProvider->getVendorTags(
-        [&](auto status, const auto& vendorTagSecs) {
-            ALOGI("getVendorTags returns status:%d numSections %zu",
-                    (int)status, vendorTagSecs.size());
-            for (size_t i = 0; i < vendorTagSecs.size(); i++) {
-                ALOGI("Vendor tag section %zu name %s",
-                        i, vendorTagSecs[i].sectionName.c_str());
-                for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
-                    const auto& tag = vendorTagSecs[i].tags[j];
-                    ALOGI("Vendor tag id %u name %s type %d",
-                            tag.tagId,
-                            tag.tagName.c_str(),
-                            (int) tag.tagType);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        ret = provider.second->getVendorTags(
+            [&](auto status, const auto& vendorTagSecs) {
+                ALOGI("getVendorTags returns status:%d numSections %zu",
+                        (int)status, vendorTagSecs.size());
+                for (size_t i = 0; i < vendorTagSecs.size(); i++) {
+                    ALOGI("Vendor tag section %zu name %s",
+                            i, vendorTagSecs[i].sectionName.c_str());
+                    for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
+                        const auto& tag = vendorTagSecs[i].tags[j];
+                        ALOGI("Vendor tag id %u name %s type %d",
+                                tag.tagId,
+                                tag.tagName.c_str(),
+                                (int) tag.tagType);
+                    }
                 }
-            }
-            ASSERT_EQ(Status::OK, status);
-        });
-    ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(Status::OK, status);
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 // Test if ICameraProvider::setCallback returns Status::OK
 TEST_F(CameraHidlTest, setCallback) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     struct ProviderCb : public ICameraProviderCallback {
         virtual Return<void> cameraDeviceStatusChange(
                 const hidl_string& cameraDeviceName,
@@ -828,37 +1107,45 @@
         }
     };
     sp<ProviderCb> cb = new ProviderCb;
-    auto status = env->mProvider->setCallback(cb);
-    ASSERT_TRUE(status.isOk());
-    ASSERT_EQ(Status::OK, status);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        auto status = provider.second->setCallback(cb);
+        ASSERT_TRUE(status.isOk());
+        ASSERT_EQ(Status::OK, status);
+    }
 }
 
 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
 TEST_F(CameraHidlTest, getCameraDeviceInterface) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device3_2) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device3_2, nullptr);
-                });
-            ASSERT_TRUE(ret.isOk());
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device1) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device1, nullptr);
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device3_2) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device3_2, nullptr);
+                    });
+                ASSERT_TRUE(ret.isOk());
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device1) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device1, nullptr);
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -866,60 +1153,66 @@
 // Verify that the device resource cost can be retrieved and the values are
 // sane.
 TEST_F(CameraHidlTest, getResourceCost) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("getResourceCost: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("getResourceCost: Testing camera device %s", name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            ret = device3_2->getResourceCost(
-                [&](auto status, const auto& resourceCost) {
-                    ALOGI("getResourceCost returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ALOGI("    Resource cost is %d", resourceCost.resourceCost);
-                    ASSERT_LE(resourceCost.resourceCost, 100u);
-                    for (const auto& name : resourceCost.conflictingDevices) {
-                        ALOGI("    Conflicting device: %s", name.c_str());
-                    }
-                });
-            ASSERT_TRUE(ret.isOk());
-        } else {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("getResourceCost: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+                ret = device3_2->getResourceCost(
+                    [&](auto status, const auto& resourceCost) {
+                        ALOGI("getResourceCost returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ALOGI("    Resource cost is %d", resourceCost.resourceCost);
+                        ASSERT_LE(resourceCost.resourceCost, 100u);
+                        for (const auto& name : resourceCost.conflictingDevices) {
+                            ALOGI("    Conflicting device: %s", name.c_str());
+                        }
+                    });
+                ASSERT_TRUE(ret.isOk());
+            } else {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("getResourceCost: Testing camera device %s", name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            ret = device1->getResourceCost(
-                [&](auto status, const auto& resourceCost) {
-                    ALOGI("getResourceCost returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ALOGI("    Resource cost is %d", resourceCost.resourceCost);
-                    ASSERT_LE(resourceCost.resourceCost, 100u);
-                    for (const auto& name : resourceCost.conflictingDevices) {
-                        ALOGI("    Conflicting device: %s", name.c_str());
-                    }
-                });
-            ASSERT_TRUE(ret.isOk());
+                ret = device1->getResourceCost(
+                    [&](auto status, const auto& resourceCost) {
+                        ALOGI("getResourceCost returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ALOGI("    Resource cost is %d",
+                              resourceCost.resourceCost);
+                        ASSERT_LE(resourceCost.resourceCost, 100u);
+                        for (const auto& name : resourceCost.conflictingDevices) {
+                            ALOGI("    Conflicting device: %s", name.c_str());
+                        }
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -927,126 +1220,143 @@
 // Verify that the static camera info can be retrieved
 // successfully.
 TEST_F(CameraHidlTest, getCameraInfo) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("getCameraCharacteristics: Testing camera device %s",
+                      name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            ret = device1->getCameraInfo(
-                [&](auto status, const auto& info) {
-                    ALOGI("getCameraInfo returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    switch(info.orientation) {
-                        case 0:
-                        case 90:
-                        case 180:
-                        case 270:
-                            //Expected cases
-                            ALOGI("camera orientation: %d", info.orientation);
-                            break;
-                        default:
-                            FAIL() << "Unexpected camera orientation:" << info.orientation;
-                    }
-                    switch(info.facing) {
-                        case CameraFacing::BACK:
-                        case CameraFacing::FRONT:
-                        case CameraFacing::EXTERNAL:
-                            //Expected cases
-                            ALOGI("camera facing: %d", info.facing);
-                            break;
-                        default:
-                            FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> (info.facing);
-                    }
-                });
-            ASSERT_TRUE(ret.isOk());
+                ret = device1->getCameraInfo(
+                    [&](auto status, const auto& info) {
+                        ALOGI("getCameraInfo returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        switch(info.orientation) {
+                            case 0:
+                            case 90:
+                            case 180:
+                            case 270:
+                                //Expected cases
+                                ALOGI("camera orientation: %d", info.orientation);
+                                break;
+                            default:
+                                FAIL() << "Unexpected camera orientation:" << info.orientation;
+                        }
+                        switch(info.facing) {
+                            case CameraFacing::BACK:
+                            case CameraFacing::FRONT:
+                            case CameraFacing::EXTERNAL:
+                                //Expected cases
+                                ALOGI("camera facing: %d", info.facing);
+                                break;
+                            default:
+                                FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> (
+                                        info.facing);
+                        }
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Check whether preview window can be configured
 TEST_F(CameraHidlTest, setPreviewWindow) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-                    openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1,
-                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1,
+                        &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
 
-            Return<void> ret;
-            ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                Return<void> ret;
+                ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Verify that setting preview window fails in case device is not open
 TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("getCameraCharacteristics: Testing camera device %s",
+                      name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
+                Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
+            }
         }
     }
 }
 
 // Start and stop preview checking whether it gets enabled in between.
 TEST_F(CameraHidlTest, startStopPreview) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-                    openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1,
-                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1,
+                        &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
 
-            startPreview(device1);
+                startPreview(device1);
 
-            Return<bool> returnBoolStatus = device1->previewEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_TRUE(returnBoolStatus);
+                Return<bool> returnBoolStatus = device1->previewEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_TRUE(returnBoolStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
@@ -1054,599 +1364,646 @@
 // Start preview without active preview window. Preview should start as soon
 // as a valid active window gets configured.
 TEST_F(CameraHidlTest, startStopPreviewDelayed) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            startPreview(device1);
+                startPreview(device1);
 
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
 
-            //Preview should get enabled now
-            Return<bool> returnBoolStatus = device1->previewEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_TRUE(returnBoolStatus);
+                //Preview should get enabled now
+                Return<bool> returnBoolStatus = device1->previewEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_TRUE(returnBoolStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Verify that image capture behaves as expected along with preview callbacks.
 TEST_F(CameraHidlTest, takePicture) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                }
+
+                enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                              device1);
+                startPreview(device1);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
+                }
+
+                disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                                device1);
+                enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
+                        device1);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                }
+
+                Return<Status> returnStatus = device1->takePicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
+                }
+
+                disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
+                        device1);
+                stopPreviewAndClose(device1);
             }
-
-            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
-            startPreview(device1);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
-            }
-
-            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
-                            device1);
-            enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
-                    device1);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-            }
-
-            Return<Status> returnStatus = device1->takePicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
-            }
-
-            disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
-                    device1);
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // Image capture should fail in case preview didn't get enabled first.
 TEST_F(CameraHidlTest, takePictureFail) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            Return<Status> returnStatus = device1->takePicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_NE(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->takePicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_NE(Status::OK, returnStatus);
 
-            Return<void> ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Verify that image capture can be cancelled.
 TEST_F(CameraHidlTest, cancelPicture) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
 
-            Return<Status> returnStatus = device1->takePicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->takePicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            returnStatus = device1->cancelPicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                returnStatus = device1->cancelPicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Image capture cancel should fail when image capture is not running.
 TEST_F(CameraHidlTest, cancelPictureFail) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
 
-            Return<Status> returnStatus = device1->cancelPicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_NE(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->cancelPicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_NE(Status::OK, returnStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Test basic video recording.
 TEST_F(CameraHidlTest, startStopRecording) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                }
 
-            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
-            startPreview(device1);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-                mVideoBufferIndex = UINT32_MAX;
-            }
-
-            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
-
-            bool videoMetaEnabled = false;
-            Return<Status> returnStatus = device1->storeMetaDataInBuffers(true);
-            ASSERT_TRUE(returnStatus.isOk());
-            // It is allowed for devices to not support this feature
-            ASSERT_TRUE((Status::OK == returnStatus) ||
-                    (Status::OPERATION_NOT_SUPPORTED == returnStatus));
-            if (Status::OK == returnStatus) {
-                videoMetaEnabled = true;
-            }
-
-            enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
-            Return<bool> returnBoolStatus = device1->recordingEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_FALSE(returnBoolStatus);
-
-            returnStatus = device1->startRecording();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
-                ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
-                disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
+                enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
                         device1);
-            }
+                startPreview(device1);
 
-            returnBoolStatus = device1->recordingEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_TRUE(returnBoolStatus);
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                    mVideoBufferIndex = UINT32_MAX;
+                }
 
-            Return<void> ret;
-            if (videoMetaEnabled) {
-                ret = device1->releaseRecordingFrameHandle(mVideoData,
-                        mVideoBufferIndex, mVideoNativeHandle);
+                disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                        device1);
+
+                bool videoMetaEnabled = false;
+                Return<Status> returnStatus = device1->storeMetaDataInBuffers(
+                        true);
+                ASSERT_TRUE(returnStatus.isOk());
+                // It is allowed for devices to not support this feature
+                ASSERT_TRUE((Status::OK == returnStatus) ||
+                        (Status::OPERATION_NOT_SUPPORTED == returnStatus));
+                if (Status::OK == returnStatus) {
+                    videoMetaEnabled = true;
+                }
+
+                enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
+                        device1);
+                Return<bool> returnBoolStatus = device1->recordingEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_FALSE(returnBoolStatus);
+
+                returnStatus = device1->startRecording();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
+                    ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
+                    disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
+                            device1);
+                }
+
+                returnBoolStatus = device1->recordingEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_TRUE(returnBoolStatus);
+
+                Return<void> ret;
+                if (videoMetaEnabled) {
+                    ret = device1->releaseRecordingFrameHandle(mVideoData,
+                            mVideoBufferIndex, mVideoNativeHandle);
+                    ASSERT_TRUE(ret.isOk());
+                } else {
+                    ret = device1->releaseRecordingFrame(mVideoData,
+                            mVideoBufferIndex);
+                    ASSERT_TRUE(ret.isOk());
+                }
+
+                ret = device1->stopRecording();
                 ASSERT_TRUE(ret.isOk());
-            } else {
-                ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex);
-                ASSERT_TRUE(ret.isOk());
+
+                stopPreviewAndClose(device1);
             }
-
-            ret = device1->stopRecording();
-            ASSERT_TRUE(ret.isOk());
-
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // It shouldn't be possible to start recording without enabling preview first.
 TEST_F(CameraHidlTest, startRecordingFail) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            Return<bool> returnBoolStatus = device1->recordingEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_FALSE(returnBoolStatus);
+                Return<bool> returnBoolStatus = device1->recordingEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_FALSE(returnBoolStatus);
 
-            Return<Status> returnStatus = device1->startRecording();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_NE(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->startRecording();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_NE(Status::OK, returnStatus);
 
-            Return<void> ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Check autofocus support if available.
 TEST_F(CameraHidlTest, autoFocus) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
-            CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
-            CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
+                CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
+                CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
-                    CameraParameters::FOCUS_MODE_AUTO)) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
-            }
-
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-            enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
-
-            for (auto &iter : focusModes) {
                 if (Status::OK != isAutoFocusModeAvailable(cameraParams,
-                        iter)) {
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
                     continue;
                 }
 
-                cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
-                setParameters(device1, cameraParams);
-                {
-                    std::unique_lock<std::mutex> l(mLock);
-                    mNotifyMessage = NotifyCallbackMsg::ERROR;
-                }
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+                enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
 
-                Return<Status> returnStatus = device1->autoFocus();
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
+                for (auto &iter : focusModes) {
+                    if (Status::OK != isAutoFocusModeAvailable(cameraParams,
+                            iter)) {
+                        continue;
+                    }
 
-                {
-                    std::unique_lock<std::mutex> l(mLock);
-                    while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
-                        auto timeout = std::chrono::system_clock::now() +
-                                std::chrono::seconds(kAutoFocusTimeoutSec);
-                        ASSERT_NE(std::cv_status::timeout,
-                                mResultCondition.wait_until(l, timeout));
+                    cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
+                    setParameters(device1, cameraParams);
+                    {
+                        std::unique_lock<std::mutex> l(mLock);
+                        mNotifyMessage = NotifyCallbackMsg::ERROR;
+                    }
+
+                    Return<Status> returnStatus = device1->autoFocus();
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+
+                    {
+                        std::unique_lock<std::mutex> l(mLock);
+                        while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
+                            auto timeout = std::chrono::system_clock::now() +
+                                    std::chrono::seconds(kAutoFocusTimeoutSec);
+                            ASSERT_NE(std::cv_status::timeout,
+                                    mResultCondition.wait_until(l, timeout));
+                        }
                     }
                 }
-            }
 
-            disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
-            stopPreviewAndClose(device1);
+                disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // In case autofocus is supported verify that it can be cancelled.
 TEST_F(CameraHidlTest, cancelAutoFocus) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
-                    CameraParameters::FOCUS_MODE_AUTO)) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
+                if (Status::OK != isAutoFocusModeAvailable(cameraParams,
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+
+                // It should be fine to call before preview starts.
+                ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
+
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+
+                // It should be fine to call after preview starts too.
+                Return<Status> returnStatus = device1->cancelAutoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                returnStatus = device1->autoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                returnStatus = device1->cancelAutoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                stopPreviewAndClose(device1);
             }
-
-            // It should be fine to call before preview starts.
-            ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
-
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-
-            // It should be fine to call after preview starts too.
-            Return<Status> returnStatus = device1->cancelAutoFocus();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            returnStatus = device1->autoFocus();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            returnStatus = device1->cancelAutoFocus();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // Check whether face detection is available and try to enable&disable.
 TEST_F(CameraHidlTest, sendCommandFaceDetection) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            int32_t hwFaces = cameraParams.getInt(
-                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
-            int32_t swFaces = cameraParams.getInt(
-                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
-            if ((0 >= hwFaces) && (0 >= swFaces)) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
+                int32_t hwFaces = cameraParams.getInt(
+                        CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
+                int32_t swFaces = cameraParams.getInt(
+                        CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
+                if ((0 >= hwFaces) && (0 >= swFaces)) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+
+                if (0 < hwFaces) {
+                    Return<Status> returnStatus = device1->sendCommand(
+                            CommandType::START_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_HW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                    // TODO(epeev) : Enable and check for face notifications
+                    returnStatus = device1->sendCommand(
+                            CommandType::STOP_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_HW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                }
+
+                if (0 < swFaces) {
+                    Return<Status> returnStatus = device1->sendCommand(
+                            CommandType::START_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_SW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                    // TODO(epeev) : Enable and check for face notifications
+                    returnStatus = device1->sendCommand(
+                            CommandType::STOP_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_SW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                }
+
+                stopPreviewAndClose(device1);
             }
-
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-
-            if (0 < hwFaces) {
-                Return<Status> returnStatus = device1->sendCommand(
-                        CommandType::START_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_HW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-                // TODO(epeev) : Enable and check for face notifications
-                returnStatus = device1->sendCommand(
-                        CommandType::STOP_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_HW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-            }
-
-            if (0 < swFaces) {
-                Return<Status> returnStatus = device1->sendCommand(
-                        CommandType::START_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_SW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-                // TODO(epeev) : Enable and check for face notifications
-                returnStatus = device1->sendCommand(
-                        CommandType::STOP_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_SW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-            }
-
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // Check whether smooth zoom is available and try to enable&disable.
 TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            const char *smoothZoomStr = cameraParams.get(
-                    CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
-            bool smoothZoomSupported = ((nullptr != smoothZoomStr) &&
-                    (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ?
-                            true : false;
-            if (!smoothZoomSupported) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
+                const char *smoothZoomStr = cameraParams.get(
+                        CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
+                bool smoothZoomSupported = ((nullptr != smoothZoomStr) &&
+                        (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ?
+                                true : false;
+                if (!smoothZoomSupported) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+
+                int32_t maxZoom = cameraParams.getInt(
+                        CameraParameters::KEY_MAX_ZOOM);
+                ASSERT_TRUE(0 < maxZoom);
+
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+                setParameters(device1, cameraParams);
+
+                Return<Status> returnStatus = device1->sendCommand(
+                        CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                // TODO(epeev) : Enable and check for face notifications
+                returnStatus = device1->sendCommand(
+                        CommandType::STOP_SMOOTH_ZOOM, 0, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                stopPreviewAndClose(device1);
             }
-
-            int32_t maxZoom = cameraParams.getInt(
-                    CameraParameters::KEY_MAX_ZOOM);
-            ASSERT_TRUE(0 < maxZoom);
-
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-            setParameters(device1, cameraParams);
-
-            Return<Status> returnStatus = device1->sendCommand(
-                    CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-            // TODO(epeev) : Enable and check for face notifications
-            returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM,
-                    0, 0);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // Basic sanity tests related to camera parameters.
 TEST_F(CameraHidlTest, getSetParameters) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            ::android::CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            int32_t width, height;
-            cameraParams.getPictureSize(&width, &height);
-            ASSERT_TRUE((0 < width) && (0 < height));
-            cameraParams.getPreviewSize(&width, &height);
-            ASSERT_TRUE((0 < width) && (0 < height));
-            int32_t minFps, maxFps;
-            cameraParams.getPreviewFpsRange(&minFps, &maxFps);
-            ASSERT_TRUE((0 < minFps) && (0 < maxFps));
-            ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
-            ASSERT_NE(nullptr, cameraParams.getPictureFormat());
-            ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG,
-                    cameraParams.getPictureFormat()) == 0);
+                int32_t width, height;
+                cameraParams.getPictureSize(&width, &height);
+                ASSERT_TRUE((0 < width) && (0 < height));
+                cameraParams.getPreviewSize(&width, &height);
+                ASSERT_TRUE((0 < width) && (0 < height));
+                int32_t minFps, maxFps;
+                cameraParams.getPreviewFpsRange(&minFps, &maxFps);
+                ASSERT_TRUE((0 < minFps) && (0 < maxFps));
+                ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
+                ASSERT_NE(nullptr, cameraParams.getPictureFormat());
+                ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG,
+                        cameraParams.getPictureFormat()) == 0);
 
-            const char *flashMode = cameraParams.get(
-                    CameraParameters::KEY_FLASH_MODE);
-            ASSERT_TRUE((nullptr == flashMode) || (strcmp(
-                    CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
+                const char *flashMode = cameraParams.get(
+                        CameraParameters::KEY_FLASH_MODE);
+                ASSERT_TRUE((nullptr == flashMode) || (strcmp(
+                        CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
 
-            const char *wbMode = cameraParams.get(
-                    CameraParameters::KEY_WHITE_BALANCE);
-            ASSERT_TRUE((nullptr == wbMode) || (strcmp(
-                    CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
+                const char *wbMode = cameraParams.get(
+                        CameraParameters::KEY_WHITE_BALANCE);
+                ASSERT_TRUE((nullptr == wbMode) || (strcmp(
+                        CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
 
-            const char *effect = cameraParams.get(CameraParameters::KEY_EFFECT);
-            ASSERT_TRUE((nullptr == effect) || (strcmp(
-                    CameraParameters::EFFECT_NONE, effect) == 0));
+                const char *effect = cameraParams.get(
+                        CameraParameters::KEY_EFFECT);
+                ASSERT_TRUE((nullptr == effect) || (strcmp(
+                        CameraParameters::EFFECT_NONE, effect) == 0));
 
-            ::android::Vector<::android::Size> previewSizes;
-            cameraParams.getSupportedPreviewSizes(previewSizes);
-            ASSERT_FALSE(previewSizes.empty());
-            ::android::Vector<::android::Size> pictureSizes;
-            cameraParams.getSupportedPictureSizes(pictureSizes);
-            ASSERT_FALSE(pictureSizes.empty());
-            const char *previewFormats = cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
-            ASSERT_NE(nullptr, previewFormats);
-            ::android::String8 previewFormatsString(previewFormats);
-            ASSERT_TRUE(previewFormatsString.contains(
-                    CameraParameters::PIXEL_FORMAT_YUV420SP));
-            ASSERT_NE(nullptr, cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
-            ASSERT_NE(nullptr, cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
-            const char *focusModes = cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
-            ASSERT_NE(nullptr, focusModes);
-            ::android::String8 focusModesString(focusModes);
-            const char *focusMode = cameraParams.get(
-                    CameraParameters::KEY_FOCUS_MODE);
-            ASSERT_NE(nullptr, focusMode);
-            // Auto focus mode should be default
-            if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) {
-                ASSERT_TRUE(strcmp(
-                        CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
+                ::android::Vector<Size> previewSizes;
+                cameraParams.getSupportedPreviewSizes(previewSizes);
+                ASSERT_FALSE(previewSizes.empty());
+                ::android::Vector<Size> pictureSizes;
+                cameraParams.getSupportedPictureSizes(pictureSizes);
+                ASSERT_FALSE(pictureSizes.empty());
+                const char *previewFormats = cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
+                ASSERT_NE(nullptr, previewFormats);
+                ::android::String8 previewFormatsString(previewFormats);
+                ASSERT_TRUE(previewFormatsString.contains(
+                        CameraParameters::PIXEL_FORMAT_YUV420SP));
+                ASSERT_NE(nullptr, cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
+                ASSERT_NE(nullptr, cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
+                const char *focusModes = cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
+                ASSERT_NE(nullptr, focusModes);
+                ::android::String8 focusModesString(focusModes);
+                const char *focusMode = cameraParams.get(
+                        CameraParameters::KEY_FOCUS_MODE);
+                ASSERT_NE(nullptr, focusMode);
+                // Auto focus mode should be default
+                if (focusModesString.contains(
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                    ASSERT_TRUE(strcmp(
+                            CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
+                }
+                ASSERT_TRUE(0 < cameraParams.getInt(
+                        CameraParameters::KEY_FOCAL_LENGTH));
+                int32_t horizontalViewAngle = cameraParams.getInt(
+                        CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
+                ASSERT_TRUE((0 < horizontalViewAngle) &&
+                            (360 >= horizontalViewAngle));
+                int32_t verticalViewAngle = cameraParams.getInt(
+                        CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
+                ASSERT_TRUE((0 < verticalViewAngle) &&
+                            (360 >= verticalViewAngle));
+                int32_t jpegQuality = cameraParams.getInt(
+                        CameraParameters::KEY_JPEG_QUALITY);
+                ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
+                int32_t jpegThumbQuality = cameraParams.getInt(
+                        CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
+                ASSERT_TRUE((1 <= jpegThumbQuality) &&
+                            (100 >= jpegThumbQuality));
+
+                cameraParams.setPictureSize(pictureSizes[0].width,
+                        pictureSizes[0].height);
+                cameraParams.setPreviewSize(previewSizes[0].width,
+                        previewSizes[0].height);
+
+                setParameters(device1, cameraParams);
+                getParameters(device1, &cameraParams /*out*/);
+
+                cameraParams.getPictureSize(&width, &height);
+                ASSERT_TRUE((pictureSizes[0].width == width) &&
+                        (pictureSizes[0].height == height));
+                cameraParams.getPreviewSize(&width, &height);
+                ASSERT_TRUE((previewSizes[0].width == width) &&
+                        (previewSizes[0].height == height));
+
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
             }
-            ASSERT_TRUE(0 < cameraParams.getInt(
-                    CameraParameters::KEY_FOCAL_LENGTH));
-            int32_t horizontalViewAngle = cameraParams.getInt(
-                    CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
-            ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle));
-            int32_t verticalViewAngle = cameraParams.getInt(
-                    CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
-            ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle));
-            int32_t jpegQuality = cameraParams.getInt(
-                    CameraParameters::KEY_JPEG_QUALITY);
-            ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
-            int32_t jpegThumbQuality = cameraParams.getInt(
-                    CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
-            ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality));
-
-            cameraParams.setPictureSize(pictureSizes[0].width,
-                    pictureSizes[0].height);
-            cameraParams.setPreviewSize(previewSizes[0].width,
-                    previewSizes[0].height);
-
-            setParameters(device1, cameraParams);
-            getParameters(device1, &cameraParams /*out*/);
-
-            cameraParams.getPictureSize(&width, &height);
-            ASSERT_TRUE((pictureSizes[0].width == width) &&
-                    (pictureSizes[0].height == height));
-            cameraParams.getPreviewSize(&width, &height);
-            ASSERT_TRUE((previewSizes[0].width == width) &&
-                    (previewSizes[0].height == height));
-
-            Return<void> ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -1654,39 +2011,50 @@
 // Verify that the static camera characteristics can be retrieved
 // successfully.
 TEST_F(CameraHidlTest, getCameraCharacteristics) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("getCameraCharacteristics: Testing camera device %s",
+                      name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            ret = device3_2->getCameraCharacteristics(
-                [&](auto status, const auto& chars) {
-                    ALOGI("getCameraCharacteristics returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    const camera_metadata_t* metadata = (camera_metadata_t*) chars.data();
-                    size_t expectedSize = chars.size();
-                    int result = validate_camera_metadata_structure(metadata, &expectedSize);
-                    ASSERT_TRUE(result == 0 || result == CAMERA_METADATA_VALIDATION_SHIFTED);
-                    size_t entryCount = get_camera_metadata_entry_count(metadata);
-                    // TODO: we can do better than 0 here. Need to check how many required
-                    // characteristics keys we've defined.
-                    ASSERT_GT(entryCount, 0u);
-                    ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
-                });
-            ASSERT_TRUE(ret.isOk());
+                ret = device3_2->getCameraCharacteristics(
+                    [&](auto status, const auto& chars) {
+                        ALOGI("getCameraCharacteristics returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        const camera_metadata_t* metadata =
+                                (camera_metadata_t*) chars.data();
+                        size_t expectedSize = chars.size();
+                        int result = validate_camera_metadata_structure(
+                                metadata, &expectedSize);
+                        ASSERT_TRUE((result == 0) ||
+                                (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+                        size_t entryCount = get_camera_metadata_entry_count(
+                                metadata);
+                        // TODO: we can do better than 0 here. Need to check how many required
+                        // characteristics keys we've defined.
+                        ASSERT_GT(entryCount, 0u);
+                        ALOGI("getCameraCharacteristics metadata entry count is %zu",
+                              entryCount);
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -1694,252 +2062,273 @@
 //In case it is supported verify that torch can be enabled.
 //Check for corresponding toch callbacks as well.
 TEST_F(CameraHidlTest, setTorchMode) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    bool torchControlSupported = false;
-    Return<void> ret;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        bool torchControlSupported = false;
+        Return<void> ret;
 
-    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
-        [&](auto status, bool support) {
-            ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
-                    (int)status, support);
-            ASSERT_EQ(Status::OK, status);
-            torchControlSupported = support;
-        });
+        ret = provider.second->isSetTorchModeSupported(
+            [&](auto status, bool support) {
+                ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
+                        (int)status, support);
+                ASSERT_EQ(Status::OK, status);
+                torchControlSupported = support;
+            });
 
 
-    sp<TorchProviderCb> cb = new TorchProviderCb(this);
-    Return<Status> returnStatus = env->mProvider->setCallback(cb);
-    ASSERT_TRUE(returnStatus.isOk());
-    ASSERT_EQ(Status::OK, returnStatus);
+        sp<TorchProviderCb> cb = new TorchProviderCb(this);
+        Return<Status> returnStatus = provider.second->setCallback(cb);
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(Status::OK, returnStatus);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("setTorchMode: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("setTorchMode: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-            returnStatus = device3_2->setTorchMode(TorchMode::ON);
-            ASSERT_TRUE(returnStatus.isOk());
-            if (!torchControlSupported) {
-                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
-            } else {
-                ASSERT_TRUE(returnStatus == Status::OK ||
-                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
-                if (returnStatus == Status::OK) {
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                returnStatus = device3_2->setTorchMode(TorchMode::ON);
+                ASSERT_TRUE(returnStatus.isOk());
+                if (!torchControlSupported) {
+                    ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+                } else {
+                    ASSERT_TRUE(returnStatus == Status::OK ||
+                                returnStatus == Status::OPERATION_NOT_SUPPORTED);
+                    if (returnStatus == Status::OK) {
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_ON,
+                                    mTorchStatus);
+                            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
-                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-                    }
 
-                    returnStatus = device3_2->setTorchMode(TorchMode::OFF);
-                    ASSERT_TRUE(returnStatus.isOk());
-                    ASSERT_EQ(Status::OK, returnStatus);
+                        returnStatus = device3_2->setTorchMode(TorchMode::OFF);
+                        ASSERT_TRUE(returnStatus.isOk());
+                        ASSERT_EQ(Status::OK, returnStatus);
 
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF,
+                                    mTorchStatus);
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
                     }
                 }
-            }
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("dumpState: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("dumpState: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-            returnStatus = device1->setTorchMode(TorchMode::ON);
-            ASSERT_TRUE(returnStatus.isOk());
-            if (!torchControlSupported) {
-                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
-            } else {
-                ASSERT_TRUE(returnStatus == Status::OK ||
-                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
-                if (returnStatus == Status::OK) {
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                returnStatus = device1->setTorchMode(TorchMode::ON);
+                ASSERT_TRUE(returnStatus.isOk());
+                if (!torchControlSupported) {
+                    ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+                } else {
+                    ASSERT_TRUE(returnStatus == Status::OK ||
+                                returnStatus == Status::OPERATION_NOT_SUPPORTED);
+                    if (returnStatus == Status::OK) {
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_ON,
+                                    mTorchStatus);
+                            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
-                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-                    }
 
-                    returnStatus = device1->setTorchMode(TorchMode::OFF);
-                    ASSERT_TRUE(returnStatus.isOk());
-                    ASSERT_EQ(Status::OK, returnStatus);
+                        returnStatus = device1->setTorchMode(TorchMode::OFF);
+                        ASSERT_TRUE(returnStatus.isOk());
+                        ASSERT_EQ(Status::OK, returnStatus);
 
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF,
+                                    mTorchStatus);
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
                     }
                 }
+                ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
             }
-            ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
         }
-    }
 
-    returnStatus = env->mProvider->setCallback(nullptr);
-    ASSERT_TRUE(returnStatus.isOk());
-    ASSERT_EQ(Status::OK, returnStatus);
+        returnStatus = provider.second->setCallback(nullptr);
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(Status::OK, returnStatus);
+    }
 }
 
 // Check dump functionality.
 TEST_F(CameraHidlTest, dumpState) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    Return<void> ret;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        Return<void> ret;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("dumpState: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<ICameraDevice> device3_2;
+                ALOGI("dumpState: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            ret= device3_2->dumpState(handle);
-            ASSERT_TRUE(ret.isOk());
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("dumpState: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                ret= device3_2->dumpState(handle);
+                ASSERT_TRUE(ret.isOk());
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("dumpState: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            Return<Status> returnStatus = device1->dumpState(handle);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                Return<Status> returnStatus = device1->dumpState(handle);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
+            }
         }
     }
 }
 
 // Open, dumpStates, then close
 TEST_F(CameraHidlTest, openClose) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    Return<void> ret;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        Return<void> ret;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("openClose: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("openClose: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            ret = device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-            ASSERT_TRUE(ret.isOk());
+                sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
+                sp<ICameraDeviceSession> session;
+                ret = device3_2->open(
+                    cb,
+                    [&](auto status, const auto& newSession) {
+                        ALOGI("device::open returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(newSession, nullptr);
+                        session = newSession;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            ret = device3_2->dumpState(handle);
-            ASSERT_TRUE(ret.isOk());
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                ret = device3_2->dumpState(handle);
+                ASSERT_TRUE(ret.isOk());
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
 
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
-            // TODO: test all session API calls return INTERNAL_ERROR after close
-            // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+                // TODO: test all session API calls return INTERNAL_ERROR after close
+                // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            Return<Status> returnStatus = device1->dumpState(handle);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                Return<Status> returnStatus = device1->dumpState(handle);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
 
-            ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -1947,71 +2336,81 @@
 // Check whether all common default request settings can be sucessfully
 // constructed.
 TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            Return<void> ret;
-            ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            ret = device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW;
-                    t <= (uint32_t) RequestTemplate::MANUAL; t++) {
-                RequestTemplate reqTemplate = (RequestTemplate) t;
-                ret = session->constructDefaultRequestSettings(
-                    reqTemplate,
-                    [&](auto status, const auto& req) {
-                        ALOGI("constructDefaultRequestSettings returns status:%d", (int)status);
-                        if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
-                                reqTemplate == RequestTemplate::MANUAL) {
-                            // optional templates
-                            ASSERT_TRUE(status == Status::OK || status == Status::ILLEGAL_ARGUMENT);
-                        } else {
-                            ASSERT_EQ(Status::OK, status);
-                        }
-
-                        if (status == Status::OK) {
-                            const camera_metadata_t* metadata =
-                                (camera_metadata_t*) req.data();
-                            size_t expectedSize = req.size();
-                            int result = validate_camera_metadata_structure(
-                                    metadata, &expectedSize);
-                            ASSERT_TRUE(result == 0 || result == CAMERA_METADATA_VALIDATION_SHIFTED);
-                            size_t entryCount = get_camera_metadata_entry_count(metadata);
-                            // TODO: we can do better than 0 here. Need to check how many required
-                            // request keys we've defined for each template
-                            ASSERT_GT(entryCount, 0u);
-                            ALOGI("template %u metadata entry count is %zu", t, entryCount);
-                        } else {
-                            ASSERT_EQ(0u, req.size());
-                        }
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                Return<void> ret;
+                ALOGI("constructDefaultRequestSettings: Testing camera device %s",
+                      name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
                     });
                 ASSERT_TRUE(ret.isOk());
+
+                sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
+                sp<ICameraDeviceSession> session;
+                ret = device3_2->open(
+                    cb,
+                    [&](auto status, const auto& newSession) {
+                        ALOGI("device::open returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(newSession, nullptr);
+                        session = newSession;
+                    });
+                ASSERT_TRUE(ret.isOk());
+
+                for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW;
+                        t <= (uint32_t) RequestTemplate::MANUAL; t++) {
+                    RequestTemplate reqTemplate = (RequestTemplate) t;
+                    ret = session->constructDefaultRequestSettings(
+                        reqTemplate,
+                        [&](auto status, const auto& req) {
+                            ALOGI("constructDefaultRequestSettings returns status:%d",
+                                  (int)status);
+                            if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
+                                    reqTemplate == RequestTemplate::MANUAL) {
+                                // optional templates
+                                ASSERT_TRUE((status == Status::OK) ||
+                                        (status == Status::ILLEGAL_ARGUMENT));
+                            } else {
+                                ASSERT_EQ(Status::OK, status);
+                            }
+
+                            if (status == Status::OK) {
+                                const camera_metadata_t* metadata =
+                                    (camera_metadata_t*) req.data();
+                                size_t expectedSize = req.size();
+                                int result = validate_camera_metadata_structure(
+                                        metadata, &expectedSize);
+                                ASSERT_TRUE((result == 0) ||
+                                        (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+                                size_t entryCount =
+                                        get_camera_metadata_entry_count(metadata);
+                                // TODO: we can do better than 0 here. Need to check how many required
+                                // request keys we've defined for each template
+                                ASSERT_GT(entryCount, 0u);
+                                ALOGI("template %u metadata entry count is %zu",
+                                      t, entryCount);
+                            } else {
+                                ASSERT_EQ(0u, req.size());
+                            }
+                        });
+                    ASSERT_TRUE(ret.isOk());
+                }
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
             }
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -2019,104 +2418,94 @@
 // Verify that all supported stream formats and sizes can be configured
 // successfully.
 TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputStreams;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputStreams;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            outputStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputStreams));
-            ASSERT_NE(0u, outputStreams.size());
+                outputStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputStreams));
+                ASSERT_NE(0u, outputStreams.size());
 
-            int32_t streamId = 0;
-            for (auto &it : outputStreams) {
-                Stream stream = {streamId, StreamType::OUTPUT,
-                        static_cast<uint32_t> (it.width),
-                        static_cast<uint32_t> (it.height),
-                        static_cast<PixelFormat> (it.format), 0, 0,
-                        StreamRotation::ROTATION_0};
-                ::android::hardware::hidl_vec<Stream> streams = {stream};
-                StreamConfiguration config = {streams,
-                        StreamConfigurationMode::NORMAL_MODE};
-                ret = session->configureStreams(config, [streamId] (Status s,
-                        HalStreamConfiguration halConfig) {
-                    ASSERT_EQ(Status::OK, s);
-                    ASSERT_EQ(1u, halConfig.streams.size());
-                    ASSERT_EQ(halConfig.streams[0].id, streamId);
-                });
+                int32_t streamId = 0;
+                for (auto &it : outputStreams) {
+                    Stream stream = {streamId, StreamType::OUTPUT,
+                            static_cast<uint32_t> (it.width),
+                            static_cast<uint32_t> (it.height),
+                            static_cast<PixelFormat> (it.format), 0, 0,
+                            StreamRotation::ROTATION_0};
+                    ::android::hardware::hidl_vec<Stream> streams = {stream};
+                    StreamConfiguration config = {streams,
+                            StreamConfigurationMode::NORMAL_MODE};
+                    ret = session->configureStreams(config, [streamId] (Status s,
+                            HalStreamConfiguration halConfig) {
+                        ASSERT_EQ(Status::OK, s);
+                        ASSERT_EQ(1u, halConfig.streams.size());
+                        ASSERT_EQ(halConfig.streams[0].id, streamId);
+                    });
+                    ASSERT_TRUE(ret.isOk());
+                    streamId++;
+                }
+
+                free_camera_metadata(staticMeta);
+                ret = session->close();
                 ASSERT_TRUE(ret.isOk());
-                streamId++;
             }
-
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
 
 // Check for correct handling of invalid/incorrect configuration parameters.
 TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputStreams;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputStreams;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            outputStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputStreams));
-            ASSERT_NE(0u, outputStreams.size());
+                outputStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputStreams));
+                ASSERT_NE(0u, outputStreams.size());
 
-            int32_t streamId = 0;
-            Stream stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (0),
-                    static_cast<uint32_t> (0),
-                    static_cast<PixelFormat> (outputStreams[0].format),
-                    0, 0, StreamRotation::ROTATION_0};
-            ::android::hardware::hidl_vec<Stream> streams = {stream};
-            StreamConfiguration config = {streams,
-                    StreamConfigurationMode::NORMAL_MODE};
-            ret = session->configureStreams(config, [] (Status s,
-                    HalStreamConfiguration) {
-                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
-                            (Status::INTERNAL_ERROR == s));
-            });
-            ASSERT_TRUE(ret.isOk());
+                int32_t streamId = 0;
+                Stream stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (0),
+                        static_cast<uint32_t> (0),
+                        static_cast<PixelFormat> (outputStreams[0].format),
+                        0, 0, StreamRotation::ROTATION_0};
+                ::android::hardware::hidl_vec<Stream> streams = {stream};
+                StreamConfiguration config = {streams,
+                        StreamConfigurationMode::NORMAL_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+                                (Status::INTERNAL_ERROR == s));
+                });
+                ASSERT_TRUE(ret.isOk());
 
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<PixelFormat> (outputStreams[0].format),
-                    0, 0, StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::NORMAL_MODE};
-            ret = session->configureStreams(config, [] (Status s,
-                    HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            for (auto &it : outputStreams) {
                 stream = {streamId++, StreamType::OUTPUT,
-                        static_cast<uint32_t> (it.width),
-                        static_cast<uint32_t> (it.height),
-                        static_cast<PixelFormat> (UINT32_MAX),
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<PixelFormat> (outputStreams[0].format),
                         0, 0, StreamRotation::ROTATION_0};
                 streams[0] = stream;
                 config = {streams,
@@ -2127,24 +2516,40 @@
                 });
                 ASSERT_TRUE(ret.isOk());
 
-                stream = {streamId++, StreamType::OUTPUT,
-                        static_cast<uint32_t> (it.width),
-                        static_cast<uint32_t> (it.height),
-                        static_cast<PixelFormat> (it.format),
-                        0, 0, static_cast<StreamRotation> (UINT32_MAX)};
-                streams[0] = stream;
-                config = {streams,
-                        StreamConfigurationMode::NORMAL_MODE};
-                ret = session->configureStreams(config, [] (Status s,
-                        HalStreamConfiguration) {
-                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-                });
+                for (auto &it : outputStreams) {
+                    stream = {streamId++, StreamType::OUTPUT,
+                            static_cast<uint32_t> (it.width),
+                            static_cast<uint32_t> (it.height),
+                            static_cast<PixelFormat> (UINT32_MAX),
+                            0, 0, StreamRotation::ROTATION_0};
+                    streams[0] = stream;
+                    config = {streams,
+                            StreamConfigurationMode::NORMAL_MODE};
+                    ret = session->configureStreams(config, [] (Status s,
+                            HalStreamConfiguration) {
+                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                    });
+                    ASSERT_TRUE(ret.isOk());
+
+                    stream = {streamId++, StreamType::OUTPUT,
+                            static_cast<uint32_t> (it.width),
+                            static_cast<uint32_t> (it.height),
+                            static_cast<PixelFormat> (it.format),
+                            0, 0, static_cast<StreamRotation> (UINT32_MAX)};
+                    streams[0] = stream;
+                    config = {streams,
+                            StreamConfigurationMode::NORMAL_MODE};
+                    ret = session->configureStreams(config, [] (Status s,
+                            HalStreamConfiguration) {
+                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                    });
+                    ASSERT_TRUE(ret.isOk());
+                }
+
+                free_camera_metadata(staticMeta);
+                ret = session->close();
                 ASSERT_TRUE(ret.isOk());
             }
-
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -2152,83 +2557,86 @@
 // Check whether all supported ZSL output stream combinations can be
 // configured successfully.
 TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> inputStreams;
-    std::vector<AvailableZSLInputOutput> inputOutputMap;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> inputStreams;
+        std::vector<AvailableZSLInputOutput> inputOutputMap;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            Status rc = isZSLModeAvailable(staticMeta);
-            if (Status::METHOD_NOT_SUPPORTED == rc) {
-                ret = session->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
-            }
-            ASSERT_EQ(Status::OK, rc);
+                Status rc = isZSLModeAvailable(staticMeta);
+                if (Status::METHOD_NOT_SUPPORTED == rc) {
+                    ret = session->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+                ASSERT_EQ(Status::OK, rc);
 
-            inputStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    inputStreams));
-            ASSERT_NE(0u, inputStreams.size());
-
-            inputOutputMap.clear();
-            ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta,
-                    inputOutputMap));
-            ASSERT_NE(0u, inputOutputMap.size());
-
-            int32_t streamId = 0;
-            for (auto &inputIter : inputOutputMap) {
-                AvailableStream input;
-                ASSERT_EQ(Status::OK,
-                        findLargestSize(inputStreams, inputIter.inputFormat, input));
+                inputStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        inputStreams));
                 ASSERT_NE(0u, inputStreams.size());
 
-                AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
-                        inputIter.outputFormat};
-                std::vector<AvailableStream> outputStreams;
-                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                        outputStreams, &outputThreshold));
-                for (auto &outputIter : outputStreams) {
-                    Stream zslStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (input.width),
-                            static_cast<uint32_t> (input.height),
-                            static_cast<PixelFormat> (input.format),
-                            GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream inputStream = {streamId++, StreamType::INPUT,
-                            static_cast<uint32_t> (input.width),
-                            static_cast<uint32_t> (input.height),
-                            static_cast<PixelFormat> (input.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream outputStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (outputIter.width),
-                            static_cast<uint32_t> (outputIter.height),
-                            static_cast<PixelFormat> (outputIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
+                inputOutputMap.clear();
+                ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta,
+                        inputOutputMap));
+                ASSERT_NE(0u, inputOutputMap.size());
 
-                    ::android::hardware::hidl_vec<Stream> streams = {
-                            inputStream, zslStream, outputStream};
-                    StreamConfiguration config = {streams,
-                            StreamConfigurationMode::NORMAL_MODE};
-                    ret = session->configureStreams(config,
+                int32_t streamId = 0;
+                for (auto &inputIter : inputOutputMap) {
+                    AvailableStream input;
+                    ASSERT_EQ(Status::OK,
+                            findLargestSize(inputStreams, inputIter.inputFormat, input));
+                    ASSERT_NE(0u, inputStreams.size());
+
+                    AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
+                            inputIter.outputFormat};
+                    std::vector<AvailableStream> outputStreams;
+                    ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                            outputStreams, &outputThreshold));
+                    for (auto &outputIter : outputStreams) {
+                        Stream zslStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (input.width),
+                                static_cast<uint32_t> (input.height),
+                                static_cast<PixelFormat> (input.format),
+                                GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream inputStream = {streamId++, StreamType::INPUT,
+                                static_cast<uint32_t> (input.width),
+                                static_cast<uint32_t> (input.height),
+                                static_cast<PixelFormat> (input.format), 0, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream outputStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (outputIter.width),
+                                static_cast<uint32_t> (outputIter.height),
+                                static_cast<PixelFormat> (outputIter.format), 0, 0,
+                                StreamRotation::ROTATION_0};
+
+                        ::android::hardware::hidl_vec<Stream> streams = {
+                                inputStream, zslStream, outputStream};
+                        StreamConfiguration config = {streams,
+                                StreamConfigurationMode::NORMAL_MODE};
+                        ret = session->configureStreams(config,
                                                     [](Status s, HalStreamConfiguration halConfig) {
                                                         ASSERT_EQ(Status::OK, s);
                                                         ASSERT_EQ(3u, halConfig.streams.size());
                                                     });
-                    ASSERT_TRUE(ret.isOk());
+                        ASSERT_TRUE(ret.isOk());
+                    }
                 }
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2236,62 +2644,65 @@
 // Verify that all supported preview + still capture stream combinations
 // can be configured successfully.
 TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputBlobStreams;
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
-            static_cast<int32_t>(PixelFormat::BLOB)};
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputBlobStreams;
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
+                static_cast<int32_t>(PixelFormat::BLOB)};
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            outputBlobStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputBlobStreams, &blobThreshold));
-            ASSERT_NE(0u, outputBlobStreams.size());
+                outputBlobStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputBlobStreams, &blobThreshold));
+                ASSERT_NE(0u, outputBlobStreams.size());
 
-            outputPreviewStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputPreviewStreams, &previewThreshold));
-            ASSERT_NE(0u, outputPreviewStreams.size());
+                outputPreviewStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputPreviewStreams, &previewThreshold));
+                ASSERT_NE(0u, outputPreviewStreams.size());
 
-            int32_t streamId = 0;
-            for (auto &blobIter : outputBlobStreams) {
-                for (auto &previewIter : outputPreviewStreams) {
-                    Stream previewStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (previewIter.width),
-                            static_cast<uint32_t> (previewIter.height),
-                            static_cast<PixelFormat> (previewIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream blobStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (blobIter.width),
-                            static_cast<uint32_t> (blobIter.height),
-                            static_cast<PixelFormat> (blobIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    ::android::hardware::hidl_vec<Stream> streams = {
-                            previewStream, blobStream};
-                    StreamConfiguration config = {streams,
-                            StreamConfigurationMode::NORMAL_MODE};
-                    ret = session->configureStreams(config,
+                int32_t streamId = 0;
+                for (auto &blobIter : outputBlobStreams) {
+                    for (auto &previewIter : outputPreviewStreams) {
+                        Stream previewStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (previewIter.width),
+                                static_cast<uint32_t> (previewIter.height),
+                                static_cast<PixelFormat> (previewIter.format), 0, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream blobStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (blobIter.width),
+                                static_cast<uint32_t> (blobIter.height),
+                                static_cast<PixelFormat> (blobIter.format), 0, 0,
+                                StreamRotation::ROTATION_0};
+                        ::android::hardware::hidl_vec<Stream> streams = {
+                                previewStream, blobStream};
+                        StreamConfiguration config = {streams,
+                                StreamConfigurationMode::NORMAL_MODE};
+                        ret = session->configureStreams(config,
                                                     [](Status s, HalStreamConfiguration halConfig) {
                                                         ASSERT_EQ(Status::OK, s);
                                                         ASSERT_EQ(2u, halConfig.streams.size());
                                                     });
-                    ASSERT_TRUE(ret.isOk());
+                        ASSERT_TRUE(ret.isOk());
+                    }
                 }
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2300,89 +2711,95 @@
 // configured. Additionally check for common invalid inputs when
 // using this mode.
 TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            Status rc = isConstrainedModeAvailable(staticMeta);
-            if (Status::METHOD_NOT_SUPPORTED == rc) {
+                Status rc = isConstrainedModeAvailable(staticMeta);
+                if (Status::METHOD_NOT_SUPPORTED == rc) {
+                    ret = session->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+                ASSERT_EQ(Status::OK, rc);
+
+                AvailableStream hfrStream;
+                rc = pickConstrainedModeSize(staticMeta, hfrStream);
+                ASSERT_EQ(Status::OK, rc);
+
+                int32_t streamId = 0;
+                Stream stream = {streamId, StreamType::OUTPUT,
+                        static_cast<uint32_t> (hfrStream.width),
+                        static_cast<uint32_t> (hfrStream.height),
+                        static_cast<PixelFormat> (hfrStream.format), 0, 0,
+                        StreamRotation::ROTATION_0};
+                ::android::hardware::hidl_vec<Stream> streams = {stream};
+                StreamConfiguration config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [streamId] (Status s,
+                        HalStreamConfiguration halConfig) {
+                    ASSERT_EQ(Status::OK, s);
+                    ASSERT_EQ(1u, halConfig.streams.size());
+                    ASSERT_EQ(halConfig.streams[0].id, streamId);
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (0),
+                        static_cast<uint32_t> (0),
+                        static_cast<PixelFormat> (hfrStream.format), 0, 0,
+                        StreamRotation::ROTATION_0};
+                streams[0] = stream;
+                config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+                                (Status::INTERNAL_ERROR == s));
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<PixelFormat> (hfrStream.format), 0, 0,
+                        StreamRotation::ROTATION_0};
+                streams[0] = stream;
+                config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (hfrStream.width),
+                        static_cast<uint32_t> (hfrStream.height),
+                        static_cast<PixelFormat> (UINT32_MAX), 0, 0,
+                        StreamRotation::ROTATION_0};
+                streams[0] = stream;
+                config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                free_camera_metadata(staticMeta);
                 ret = session->close();
                 ASSERT_TRUE(ret.isOk());
-                continue;
             }
-            ASSERT_EQ(Status::OK, rc);
-
-            AvailableStream hfrStream;
-            rc = pickConstrainedModeSize(staticMeta, hfrStream);
-            ASSERT_EQ(Status::OK, rc);
-
-            int32_t streamId = 0;
-            Stream stream = {streamId, StreamType::OUTPUT,
-                    static_cast<uint32_t> (hfrStream.width),
-                    static_cast<uint32_t> (hfrStream.height),
-                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
-                    StreamRotation::ROTATION_0};
-            ::android::hardware::hidl_vec<Stream> streams = {stream};
-            StreamConfiguration config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [streamId] (Status s,
-                    HalStreamConfiguration halConfig) {
-                ASSERT_EQ(Status::OK, s);
-                ASSERT_EQ(1u, halConfig.streams.size());
-                ASSERT_EQ(halConfig.streams[0].id, streamId);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (0),
-                    static_cast<uint32_t> (0),
-                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
-                    StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
-                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
-                            (Status::INTERNAL_ERROR == s));
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
-                    StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (hfrStream.width),
-                    static_cast<uint32_t> (hfrStream.height),
-                    static_cast<PixelFormat> (UINT32_MAX), 0, 0,
-                    StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -2390,176 +2807,215 @@
 // Verify that all supported video + snapshot stream combinations can
 // be configured successfully.
 TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputBlobStreams;
-    std::vector<AvailableStream> outputVideoStreams;
-    AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
-            static_cast<int32_t>(PixelFormat::BLOB)};
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputBlobStreams;
+        std::vector<AvailableStream> outputVideoStreams;
+        AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
+                static_cast<int32_t>(PixelFormat::BLOB)};
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            outputBlobStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputBlobStreams, &blobThreshold));
-            ASSERT_NE(0u, outputBlobStreams.size());
+                outputBlobStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputBlobStreams, &blobThreshold));
+                ASSERT_NE(0u, outputBlobStreams.size());
 
-            outputVideoStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputVideoStreams, &videoThreshold));
-            ASSERT_NE(0u, outputVideoStreams.size());
+                outputVideoStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputVideoStreams, &videoThreshold));
+                ASSERT_NE(0u, outputVideoStreams.size());
 
-            int32_t streamId = 0;
-            for (auto &blobIter : outputBlobStreams) {
-                for (auto &videoIter : outputVideoStreams) {
-                    Stream videoStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (videoIter.width),
-                            static_cast<uint32_t> (videoIter.height),
-                            static_cast<PixelFormat> (videoIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream blobStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (blobIter.width),
-                            static_cast<uint32_t> (blobIter.height),
-                            static_cast<PixelFormat> (blobIter.format),
-                            GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
-                            StreamRotation::ROTATION_0};
-                    ::android::hardware::hidl_vec<Stream> streams = {
-                            videoStream, blobStream};
-                    StreamConfiguration config = {streams,
-                            StreamConfigurationMode::NORMAL_MODE};
-                    ret = session->configureStreams(config,
+                int32_t streamId = 0;
+                for (auto &blobIter : outputBlobStreams) {
+                    for (auto &videoIter : outputVideoStreams) {
+                        Stream videoStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (videoIter.width),
+                                static_cast<uint32_t> (videoIter.height),
+                                static_cast<PixelFormat> (videoIter.format),
+                                0, 0, StreamRotation::ROTATION_0};
+                        Stream blobStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (blobIter.width),
+                                static_cast<uint32_t> (blobIter.height),
+                                static_cast<PixelFormat> (blobIter.format),
+                                GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
+                                StreamRotation::ROTATION_0};
+                        ::android::hardware::hidl_vec<Stream> streams = {
+                                videoStream, blobStream};
+                        StreamConfiguration config = {streams,
+                                StreamConfigurationMode::NORMAL_MODE};
+                        ret = session->configureStreams(config,
                                                     [](Status s, HalStreamConfiguration halConfig) {
                                                         ASSERT_EQ(Status::OK, s);
                                                         ASSERT_EQ(2u, halConfig.streams.size());
                                                     });
-                    ASSERT_TRUE(ret.isOk());
+                        ASSERT_TRUE(ret.isOk());
+                    }
                 }
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Generate and verify a camera capture request
 TEST_F(CameraHidlTest, processCaptureRequestPreview) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint64_t bufferId = 1;
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint64_t bufferId = 1;
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount/*out*/);
 
-            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            Return<void> ret;
-            ret = session->constructDefaultRequestSettings(reqTemplate,
-                [&](auto status, const auto& req) {
-                    ASSERT_EQ(Status::OK, status);
-                    settings = req; });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<GraphicBuffer> gb = new GraphicBuffer(
-                previewStream.width, previewStream.height,
-                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
-                1, android_convertGralloc1To0Usage(
-                       halStreamConfig.streams[0].producerUsage,
-                       halStreamConfig.streams[0].consumerUsage));
-            ASSERT_NE(nullptr, gb.get());
-            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
-                    BufferStatus::OK, nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
-                    outputBuffer};
-            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
-                    emptyInputBuffer, outputBuffers};
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mResultBuffers.clear();
-                mResultFrameNumber = frameNumber;
-            }
-
-            Status status = Status::INTERNAL_ERROR;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            Return<void> returnStatus = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
+                std::shared_ptr<ResultMetadataQueue> resultQueue;
+                auto resultQueueRet = session->getCaptureResultMetadataQueue(
+                    [&resultQueue](const auto& descriptor) {
+                        resultQueue = std::make_shared<ResultMetadataQueue>(
+                                descriptor);
+                        if (!resultQueue->isValid() ||
+                                resultQueue->availableToWrite() <= 0) {
+                            ALOGE("%s: HAL returns empty result metadata fmq,"
+                                    " not use it", __func__);
+                            resultQueue = nullptr;
+                            // Don't use the queue onwards.
+                        }
                     });
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, status);
-            ASSERT_EQ(numRequestProcessed, 1u);
+                ASSERT_TRUE(resultQueueRet.isOk());
+                ASSERT_NE(nullptr, resultQueue);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                while (0 == mResultBuffers.size()) {
-                    auto timeout = std::chrono::system_clock::now() +
-                            std::chrono::seconds(kStreamBufferTimeoutSec);
-                    ASSERT_NE(std::cv_status::timeout,
-                            mResultCondition.wait_until(l, timeout));
+                InFlightRequest inflightReq = {1, false, supportsPartialResults,
+                        partialResultCount, resultQueue};
+
+                RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+                Return<void> ret;
+                ret = session->constructDefaultRequestSettings(reqTemplate,
+                    [&](auto status, const auto& req) {
+                        ASSERT_EQ(Status::OK, status);
+                        settings = req; });
+                ASSERT_TRUE(ret.isOk());
+
+                sp<GraphicBuffer> gb = new GraphicBuffer(
+                    previewStream.width, previewStream.height,
+                    static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
+                    1, android_convertGralloc1To0Usage(
+                           halStreamConfig.streams[0].producerUsage,
+                           halStreamConfig.streams[0].consumerUsage));
+                ASSERT_NE(nullptr, gb.get());
+                StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+                        bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                        BufferStatus::OK, nullptr, nullptr};
+                ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                        outputBuffer};
+                StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */,
+                        settings, emptyInputBuffer, outputBuffers};
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mInflightMap.clear();
+                    mInflightMap.add(frameNumber, &inflightReq);
                 }
 
-                ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
-                ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
+                Status status = Status::INTERNAL_ERROR;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                Return<void> returnStatus = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, status);
+                ASSERT_EQ(numRequestProcessed, 1u);
 
-                request.frameNumber++;
-                //Empty settings should be supported after the first call
-                //for repeating requests.
-                request.settings.setToExternal(nullptr, 0, true);
-                mResultBuffers.clear();
-                mResultFrameNumber++;
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (!inflightReq.errorCodeValid &&
+                            ((0 < inflightReq.numBuffersLeft) ||
+                                    (!inflightReq.haveResultMetadata))) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
+                    }
 
-            returnStatus = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
-                    });
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, status);
-            ASSERT_EQ(numRequestProcessed, 1u);
+                    ASSERT_FALSE(inflightReq.errorCodeValid);
+                    ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+                    ASSERT_EQ(previewStream.id,
+                              inflightReq.resultOutputBuffers[0].streamId);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                while (0 == mResultBuffers.size()) {
-                    auto timeout = std::chrono::system_clock::now() +
-                            std::chrono::seconds(kStreamBufferTimeoutSec);
-                    ASSERT_NE(std::cv_status::timeout,
-                            mResultCondition.wait_until(l, timeout));
+                    request.frameNumber++;
+                    //Empty settings should be supported after the first call
+                    //for repeating requests.
+                    request.settings.setToExternal(nullptr, 0, true);
+                    mInflightMap.clear();
+                    inflightReq = {1, false, supportsPartialResults,
+                                        partialResultCount, resultQueue};
+                    mInflightMap.add(request.frameNumber, &inflightReq);
                 }
-                ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
-                ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
-            }
 
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                returnStatus = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, status);
+                ASSERT_EQ(numRequestProcessed, 1u);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (!inflightReq.errorCodeValid &&
+                            ((0 < inflightReq.numBuffersLeft) ||
+                                    (!inflightReq.haveResultMetadata))) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
+                    }
+
+                    ASSERT_FALSE(inflightReq.errorCodeValid);
+                    ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+                    ASSERT_EQ(previewStream.id,
+                              inflightReq.resultOutputBuffers[0].streamId);
+                }
+
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2567,58 +3023,64 @@
 // Test whether an incorrect capture request with missing settings will
 // be reported correctly.
 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint64_t bufferId = 1;
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint64_t bufferId = 1;
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount /*out*/);
 
-            sp<GraphicBuffer> gb = new GraphicBuffer(
-                previewStream.width, previewStream.height,
-                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
-                1, android_convertGralloc1To0Usage(
-                       halStreamConfig.streams[0].producerUsage,
-                       halStreamConfig.streams[0].consumerUsage));
+                sp<GraphicBuffer> gb = new GraphicBuffer(
+                    previewStream.width, previewStream.height,
+                    static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
+                    1, android_convertGralloc1To0Usage(
+                           halStreamConfig.streams[0].producerUsage,
+                           halStreamConfig.streams[0].consumerUsage));
 
-            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
-                    BufferStatus::OK, nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
-                    outputBuffer};
-            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
-                    emptyInputBuffer, outputBuffers};
+                StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+                        bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                        BufferStatus::OK, nullptr, nullptr};
+                ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                        outputBuffer};
+                StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
+                        emptyInputBuffer, outputBuffers};
 
-            //Settings were not correctly initialized, we should fail here
-            Status status = Status::OK;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            Return<void> ret = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&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);
+                //Settings were not correctly initialized, we should fail here
+                Status status = Status::OK;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                Return<void> ret = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&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());
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2626,207 +3088,231 @@
 // Check whether an invalid capture request with missing output buffers
 // will be reported correctly.
 TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputBlobStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputBlobStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults/*out*/,
+                        &partialResultCount /*out*/);
 
-            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            Return<void> ret;
-            ret = session->constructDefaultRequestSettings(reqTemplate,
-                [&](auto status, const auto& req) {
-                    ASSERT_EQ(Status::OK, status);
-                    settings = req; });
-            ASSERT_TRUE(ret.isOk());
+                RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+                Return<void> ret;
+                ret = session->constructDefaultRequestSettings(reqTemplate,
+                    [&](auto status, const auto& req) {
+                        ASSERT_EQ(Status::OK, status);
+                        settings = req; });
+                ASSERT_TRUE(ret.isOk());
 
-            ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
-            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */, settings,
-                    emptyInputBuffer, emptyOutputBuffers};
+                ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
+                StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */,
+                        settings, emptyInputBuffer, emptyOutputBuffers};
 
-            //Output buffers are missing, we should fail here
-            Status status = Status::OK;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            ret = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&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);
+                //Output buffers are missing, we should fail here
+                Status status = Status::OK;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                ret = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&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());
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Generate, trigger and flush a preview request
 TEST_F(CameraHidlTest, flushPreviewRequest) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint64_t bufferId = 1;
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint64_t bufferId = 1;
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount /*out*/);
 
-            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            Return<void> ret;
-            ret = session->constructDefaultRequestSettings(reqTemplate,
-                [&](auto status, const auto& req) {
-                    ASSERT_EQ(Status::OK, status);
-                    settings = req; });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<GraphicBuffer> gb = new GraphicBuffer(
-                previewStream.width, previewStream.height,
-                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
-                1, android_convertGralloc1To0Usage(
-                       halStreamConfig.streams[0].producerUsage,
-                       halStreamConfig.streams[0].consumerUsage));
-            ASSERT_NE(nullptr, gb.get());
-            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
-                    BufferStatus::OK, nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
-                    outputBuffer};
-            const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
-                    emptyInputBuffer, outputBuffers};
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mResultBuffers.clear();
-                mErrors.clear();
-                mResultFrameNumber = frameNumber;
-            }
-
-            Status status = Status::INTERNAL_ERROR;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            ret = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
+                std::shared_ptr<ResultMetadataQueue> resultQueue;
+                auto resultQueueRet = session->getCaptureResultMetadataQueue(
+                    [&resultQueue](const auto& descriptor) {
+                        resultQueue = std::make_shared<ResultMetadataQueue>(
+                                descriptor);
+                        if (!resultQueue->isValid() ||
+                                resultQueue->availableToWrite() <= 0) {
+                            ALOGE("%s: HAL returns empty result metadata fmq,"
+                                    " not use it", __func__);
+                            resultQueue = nullptr;
+                            // Don't use the queue onwards.
+                        }
                     });
+                ASSERT_TRUE(resultQueueRet.isOk());
+                ASSERT_NE(nullptr, resultQueue);
 
-            ASSERT_TRUE(ret.isOk());
-            ASSERT_EQ(Status::OK, status);
-            ASSERT_EQ(numRequestProcessed, 1u);
-            //Flush before waiting for request to complete.
-            Return<Status> returnStatus = session->flush();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                InFlightRequest inflightReq = {1, false, supportsPartialResults,
+                        partialResultCount, resultQueue};
+                RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+                Return<void> ret;
+                ret = session->constructDefaultRequestSettings(reqTemplate,
+                    [&](auto status, const auto& req) {
+                        ASSERT_EQ(Status::OK, status);
+                        settings = req; });
+                ASSERT_TRUE(ret.isOk());
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                while ((0 == mResultBuffers.size()) && (0 == mErrors.size())) {
-                    auto timeout = std::chrono::system_clock::now() +
-                            std::chrono::seconds(kStreamBufferTimeoutSec);
-                    ASSERT_NE(std::cv_status::timeout,
-                            mResultCondition.wait_until(l, timeout));
+                sp<GraphicBuffer> gb = new GraphicBuffer(
+                    previewStream.width, previewStream.height,
+                    static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
+                    1, android_convertGralloc1To0Usage(
+                           halStreamConfig.streams[0].producerUsage,
+                           halStreamConfig.streams[0].consumerUsage));
+                ASSERT_NE(nullptr, gb.get());
+                StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+                        bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                        BufferStatus::OK, nullptr, nullptr};
+                ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                        outputBuffer};
+                const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */,
+                        settings, emptyInputBuffer, outputBuffers};
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mInflightMap.clear();
+                    mInflightMap.add(frameNumber, &inflightReq);
                 }
 
-                if (mErrors.empty()) {
-                    ASSERT_EQ(BufferStatus::OK, mResultBuffers[0].status);
-                    ASSERT_EQ(previewStream.id, mResultBuffers[0].streamId);
-                } else {
-                    for (auto &error : mErrors) {
-                        switch (error.errorCode) {
+                Status status = Status::INTERNAL_ERROR;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                ret = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&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.
+                Return<Status> returnStatus = session->flush();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (!inflightReq.errorCodeValid &&
+                            ((0 < inflightReq.numBuffersLeft) ||
+                                    (!inflightReq.haveResultMetadata))) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
+                    }
+
+                    if (!inflightReq.errorCodeValid) {
+                        ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+                        ASSERT_EQ(previewStream.id,
+                                  inflightReq.resultOutputBuffers[0].streamId);
+                    } else {
+                        switch (inflightReq.errorCode) {
                             case ErrorCode::ERROR_REQUEST:
                             case ErrorCode::ERROR_RESULT:
-                                //Expected
-                                break;
                             case ErrorCode::ERROR_BUFFER:
-                                //Expected as well
-                                ASSERT_EQ(frameNumber, error.frameNumber);
-                                ASSERT_EQ(previewStream.id, error.errorStreamId);
+                                //Expected
                                 break;
                             case ErrorCode::ERROR_DEVICE:
                             default:
-                                FAIL() <<"Unexpected error:" << static_cast<uint32_t> (error.errorCode);
+                                FAIL() << "Unexpected error:" << static_cast<uint32_t> (
+                                        inflightReq.errorCode);
                         }
                     }
+
+                    ret = session->close();
+                    ASSERT_TRUE(ret.isOk());
                 }
             }
-
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
 
 // Verify that camera flushes correctly without any pending requests.
 TEST_F(CameraHidlTest, flushEmpty) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount /*out*/);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mResultBuffers.clear();
-                mErrors.clear();
-                mResultFrameNumber = 0;
+                Return<Status> returnStatus = session->flush();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    auto timeout = std::chrono::system_clock::now() +
+                            std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
+                    ASSERT_EQ(std::cv_status::timeout,
+                            mResultCondition.wait_until(l, timeout));
+                }
+
+                Return<void> ret = session->close();
+                ASSERT_TRUE(ret.isOk());
             }
-
-            Return<Status> returnStatus = session->flush();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                auto timeout = std::chrono::system_clock::now() +
-                        std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
-                ASSERT_EQ(std::cv_status::timeout,
-                        mResultCondition.wait_until(l, timeout));
-                ASSERT_TRUE(mErrors.empty());
-                ASSERT_TRUE(mResultBuffers.empty());
-            }
-
-            Return<void> ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -3003,7 +3489,7 @@
 
 // Check whether the camera device supports specific focus mode.
 Status CameraHidlTest::isAutoFocusModeAvailable(
-        ::android::CameraParameters &cameraParams,
+        CameraParameters &cameraParams,
         const char *mode) {
     ::android::String8 focusModes(cameraParams.get(
             CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
@@ -3016,21 +3502,24 @@
 
 // Open a device session and configure a preview stream.
 void CameraHidlTest::configurePreviewStream(const std::string &name,
-        const CameraHidlEnvironment* env,
+        sp<ICameraProvider> provider,
         const AvailableStream *previewThreshold,
         sp<ICameraDeviceSession> *session /*out*/,
         Stream *previewStream /*out*/,
-        HalStreamConfiguration *halStreamConfig /*out*/) {
-    ASSERT_NE(nullptr, env);
+        HalStreamConfiguration *halStreamConfig /*out*/,
+        bool *supportsPartialResults /*out*/,
+        uint32_t *partialResultCount /*out*/) {
     ASSERT_NE(nullptr, session);
     ASSERT_NE(nullptr, previewStream);
     ASSERT_NE(nullptr, halStreamConfig);
+    ASSERT_NE(nullptr, supportsPartialResults);
+    ASSERT_NE(nullptr, partialResultCount);
 
     std::vector<AvailableStream> outputPreviewStreams;
     ::android::sp<ICameraDevice> device3_2;
     ALOGI("configureStreams: Testing camera device %s", name.c_str());
     Return<void> ret;
-    ret = env->mProvider->getCameraDeviceInterface_V3_x(
+    ret = provider->getCameraDeviceInterface_V3_x(
         name,
         [&](auto status, const auto& device) {
             ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
@@ -3062,6 +3551,14 @@
     });
     ASSERT_TRUE(ret.isOk());
 
+    camera_metadata_ro_entry entry;
+    auto status = find_camera_metadata_ro_entry(staticMeta,
+            ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
+    if ((0 == status) && (entry.count > 0)) {
+        *partialResultCount = entry.data.i32[0];
+        *supportsPartialResults = (*partialResultCount > 1);
+    }
+
     outputPreviewStreams.clear();
     auto rc = getAvailableOutputStreams(staticMeta,
             outputPreviewStreams, previewThreshold);
@@ -3088,17 +3585,16 @@
 
 // Open a device session with empty callbacks and return static metadata.
 void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
-        const CameraHidlEnvironment* env,
+        sp<ICameraProvider> provider,
         sp<ICameraDeviceSession> *session /*out*/,
         camera_metadata_t **staticMeta /*out*/) {
-    ASSERT_NE(nullptr, env);
     ASSERT_NE(nullptr, session);
     ASSERT_NE(nullptr, staticMeta);
 
     ::android::sp<ICameraDevice> device3_2;
     ALOGI("configureStreams: Testing camera device %s", name.c_str());
     Return<void> ret;
-    ret = env->mProvider->getCameraDeviceInterface_V3_x(
+    ret = provider->getCameraDeviceInterface_V3_x(
         name,
         [&](auto status, const auto& device) {
             ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
@@ -3130,13 +3626,12 @@
 
 // Open a particular camera device.
 void CameraHidlTest::openCameraDevice(const std::string &name,
-        const CameraHidlEnvironment* env,
+        sp<ICameraProvider> provider,
         sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
-    ASSERT_TRUE(nullptr != env);
     ASSERT_TRUE(nullptr != device1);
 
     Return<void> ret;
-    ret = env->mProvider->getCameraDeviceInterface_V1_x(
+    ret = provider->getCameraDeviceInterface_V1_x(
             name,
             [&](auto status, const auto& device) {
             ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
diff --git a/compatibility_matrix.26.xml b/compatibility_matrix.26.xml
index 9aa5418..8c715dd 100644
--- a/compatibility_matrix.26.xml
+++ b/compatibility_matrix.26.xml
@@ -73,7 +73,7 @@
     </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.configstore</name>
-        <version>1.0-1</version>
+        <version>1.0</version>
         <interface>
             <name>ISurfaceFlingerConfigs</name>
             <instance>default</instance>
diff --git a/compatibility_matrix.current.xml b/compatibility_matrix.current.xml
index 9603bd6..e3c4e15 100644
--- a/compatibility_matrix.current.xml
+++ b/compatibility_matrix.current.xml
@@ -73,7 +73,7 @@
     </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.configstore</name>
-        <version>1.0-1</version>
+        <version>1.0</version>
         <interface>
             <name>ISurfaceFlingerConfigs</name>
             <instance>default</instance>
diff --git a/compatibility_matrix.legacy.xml b/compatibility_matrix.legacy.xml
index 6167f25..1dbbb05 100644
--- a/compatibility_matrix.legacy.xml
+++ b/compatibility_matrix.legacy.xml
@@ -73,7 +73,7 @@
     </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.configstore</name>
-        <version>1.0-1</version>
+        <version>1.0</version>
         <interface>
             <name>ISurfaceFlingerConfigs</name>
             <instance>default</instance>
diff --git a/configstore/1.1/default/Android.mk b/configstore/1.0/default/Android.mk
similarity index 75%
rename from configstore/1.1/default/Android.mk
rename to configstore/1.0/default/Android.mk
index ac3d8b0..e017cfd 100644
--- a/configstore/1.1/default/Android.mk
+++ b/configstore/1.0/default/Android.mk
@@ -2,18 +2,17 @@
 
 ################################################################################
 include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.configstore@1.1-service
+LOCAL_MODULE := android.hardware.configstore@1.0-service
 LOCAL_PROPRIETARY_MODULE := true
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_INIT_RC := android.hardware.configstore@1.1-service.rc
+LOCAL_INIT_RC := android.hardware.configstore@1.0-service.rc
 LOCAL_SRC_FILES:= service.cpp
 
 include $(LOCAL_PATH)/surfaceflinger.mk
 
 LOCAL_SHARED_LIBRARIES := \
     android.hardware.configstore@1.0 \
-    android.hardware.configstore@1.1 \
     libhidlbase \
     libhidltransport \
     libbase \
diff --git a/configstore/1.1/default/SurfaceFlingerConfigs.cpp b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
similarity index 96%
rename from configstore/1.1/default/SurfaceFlingerConfigs.cpp
rename to configstore/1.0/default/SurfaceFlingerConfigs.cpp
index 5a040f2..3239274 100644
--- a/configstore/1.1/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
@@ -19,7 +19,7 @@
 namespace android {
 namespace hardware {
 namespace configstore {
-namespace V1_1 {
+namespace V1_0 {
 namespace implementation {
 
 // Methods from ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs
@@ -139,13 +139,10 @@
     return Void();
 }
 
-// Methods from ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs
-// follow.
-
 // Methods from ::android::hidl::base::V1_0::IBase follow.
 
 }  // namespace implementation
-}  // namespace V1_1
+}  // namespace V1_0
 }  // namespace configstore
 }  // namespace hardware
 }  // namespace android
diff --git a/configstore/1.1/default/SurfaceFlingerConfigs.h b/configstore/1.0/default/SurfaceFlingerConfigs.h
similarity index 77%
rename from configstore/1.1/default/SurfaceFlingerConfigs.h
rename to configstore/1.0/default/SurfaceFlingerConfigs.h
index 53e8ae8..32e5fc3 100644
--- a/configstore/1.1/default/SurfaceFlingerConfigs.h
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.h
@@ -1,17 +1,17 @@
-#ifndef ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
-#define ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
+#ifndef ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
+#define ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
 
-#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
 namespace android {
 namespace hardware {
 namespace configstore {
-namespace V1_1 {
+namespace V1_0 {
 namespace implementation {
 
-using ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs;
+using ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::sp;
@@ -32,16 +32,13 @@
     Return<void> maxFrameBufferAcquiredBuffers(maxFrameBufferAcquiredBuffers_cb _hidl_cb) override;
     Return<void> startGraphicsAllocatorService(startGraphicsAllocatorService_cb _hidl_cb) override;
 
-    // Methods from
-    // ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs follow.
-
     // Methods from ::android::hidl::base::V1_0::IBase follow.
 };
 
 }  // namespace implementation
-}  // namespace V1_1
+}  // namespace V1_0
 }  // namespace configstore
 }  // namespace hardware
 }  // namespace android
 
-#endif  // ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
+#endif  // ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
diff --git a/configstore/1.0/default/android.hardware.configstore@1.0-service.rc b/configstore/1.0/default/android.hardware.configstore@1.0-service.rc
new file mode 100644
index 0000000..563d854
--- /dev/null
+++ b/configstore/1.0/default/android.hardware.configstore@1.0-service.rc
@@ -0,0 +1,4 @@
+service configstore-hal-1-0 /vendor/bin/hw/android.hardware.configstore@1.0-service
+    class hal animation
+    user system
+    group system
diff --git a/configstore/1.1/default/service.cpp b/configstore/1.0/default/service.cpp
similarity index 83%
rename from configstore/1.1/default/service.cpp
rename to configstore/1.0/default/service.cpp
index 3a4cd3f..3dca739 100644
--- a/configstore/1.1/default/service.cpp
+++ b/configstore/1.0/default/service.cpp
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.configstore@1.1-service"
+#define LOG_TAG "android.hardware.configstore@1.0-service"
 
-#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <hidl/HidlTransportSupport.h>
 
 #include "SurfaceFlingerConfigs.h"
 
 using android::hardware::configureRpcThreadpool;
 using android::hardware::joinRpcThreadpool;
-using android::hardware::configstore::V1_1::ISurfaceFlingerConfigs;
-using android::hardware::configstore::V1_1::implementation::SurfaceFlingerConfigs;
+using android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
+using android::hardware::configstore::V1_0::implementation::SurfaceFlingerConfigs;
 using android::sp;
 using android::status_t;
 using android::OK;
diff --git a/configstore/1.1/default/surfaceflinger.mk b/configstore/1.0/default/surfaceflinger.mk
similarity index 100%
rename from configstore/1.1/default/surfaceflinger.mk
rename to configstore/1.0/default/surfaceflinger.mk
diff --git a/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp b/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
index 95cd30b..e501580 100644
--- a/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
+++ b/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
@@ -41,6 +41,7 @@
     virtual void SetUp() override {
         sfConfigs = ::testing::VtsHalHidlTargetTestBase::getService<
             ISurfaceFlingerConfigs>();
+        ASSERT_NE(sfConfigs, nullptr);
     }
 
     virtual void TearDown() override {}
diff --git a/configstore/1.1/Android.bp b/configstore/1.1/Android.bp
deleted file mode 100644
index 2d8cb64..0000000
--- a/configstore/1.1/Android.bp
+++ /dev/null
@@ -1,61 +0,0 @@
-// This file is autogenerated by hidl-gen. Do not edit manually.
-
-filegroup {
-    name: "android.hardware.configstore@1.1_hal",
-    srcs: [
-        "ISurfaceFlingerConfigs.hal",
-    ],
-}
-
-genrule {
-    name: "android.hardware.configstore@1.1_genc++",
-    tools: ["hidl-gen"],
-    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.1",
-    srcs: [
-        ":android.hardware.configstore@1.1_hal",
-    ],
-    out: [
-        "android/hardware/configstore/1.1/SurfaceFlingerConfigsAll.cpp",
-    ],
-}
-
-genrule {
-    name: "android.hardware.configstore@1.1_genc++_headers",
-    tools: ["hidl-gen"],
-    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.1",
-    srcs: [
-        ":android.hardware.configstore@1.1_hal",
-    ],
-    out: [
-        "android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h",
-        "android/hardware/configstore/1.1/IHwSurfaceFlingerConfigs.h",
-        "android/hardware/configstore/1.1/BnHwSurfaceFlingerConfigs.h",
-        "android/hardware/configstore/1.1/BpHwSurfaceFlingerConfigs.h",
-        "android/hardware/configstore/1.1/BsSurfaceFlingerConfigs.h",
-    ],
-}
-
-cc_library_shared {
-    name: "android.hardware.configstore@1.1",
-    defaults: ["hidl-module-defaults"],
-    generated_sources: ["android.hardware.configstore@1.1_genc++"],
-    generated_headers: ["android.hardware.configstore@1.1_genc++_headers"],
-    export_generated_headers: ["android.hardware.configstore@1.1_genc++_headers"],
-    vendor_available: true,
-    shared_libs: [
-        "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
-        "liblog",
-        "libutils",
-        "libcutils",
-        "android.hardware.configstore@1.0",
-    ],
-    export_shared_lib_headers: [
-        "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
-        "libutils",
-        "android.hardware.configstore@1.0",
-    ],
-}
diff --git a/configstore/1.1/Android.mk b/configstore/1.1/Android.mk
deleted file mode 100644
index a5fa6c4..0000000
--- a/configstore/1.1/Android.mk
+++ /dev/null
@@ -1,78 +0,0 @@
-# This file is autogenerated by hidl-gen. Do not edit manually.
-
-LOCAL_PATH := $(call my-dir)
-
-################################################################################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.configstore-V1.1-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.configstore-V1.0-java \
-    android.hidl.base-V1.0-java \
-
-
-#
-# Build ISurfaceFlingerConfigs.hal
-#
-GEN := $(intermediates)/android/hardware/configstore/V1_1/ISurfaceFlingerConfigs.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISurfaceFlingerConfigs.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.configstore@1.1::ISurfaceFlingerConfigs
-
-$(GEN): $(LOCAL_PATH)/ISurfaceFlingerConfigs.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-include $(BUILD_JAVA_LIBRARY)
-
-
-################################################################################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.configstore-V1.1-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.configstore-V1.0-java-static \
-    android.hidl.base-V1.0-java-static \
-
-
-#
-# Build ISurfaceFlingerConfigs.hal
-#
-GEN := $(intermediates)/android/hardware/configstore/V1_1/ISurfaceFlingerConfigs.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISurfaceFlingerConfigs.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.configstore@1.1::ISurfaceFlingerConfigs
-
-$(GEN): $(LOCAL_PATH)/ISurfaceFlingerConfigs.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/configstore/1.1/default/android.hardware.configstore@1.1-service.rc b/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
deleted file mode 100644
index 018ef10..0000000
--- a/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service configstore-hal /vendor/bin/hw/android.hardware.configstore@1.1-service
-    class hal animation
-    user system
-    group system
diff --git a/configstore/Android.bp b/configstore/Android.bp
index 21dc2b4..ba3e62e 100644
--- a/configstore/Android.bp
+++ b/configstore/Android.bp
@@ -2,6 +2,5 @@
 subdirs = [
     "1.0",
     "1.0/vts/functional",
-    "1.1",
     "utils",
 ]
diff --git a/current.txt b/current.txt
index 8d0785f..986e0ec 100644
--- a/current.txt
+++ b/current.txt
@@ -101,7 +101,7 @@
 4f6dedbcdd21c309dfc650acea81a096d6b242493ffe49c8d61bd3c43aad354e android.hardware.graphics.common@1.0::types
 b3aac6c3817f039964fcd62268274b3039e17bd7d0d5b40b4d1d1c7b19a1f866 android.hardware.graphics.composer@2.1::IComposer
 b19d00eb8a8b3b0034a0321f22e8f32162bf4c2aebbce6da22c025f56e459ea2 android.hardware.graphics.composer@2.1::IComposerCallback
-e992684e690dfe67a8cbeab5005bfa3fa9c2bf3d4b0b75657fb1f0c2d5dd2bae android.hardware.graphics.composer@2.1::IComposerClient
+61ee43ffe6fb6dbe8b22dc17c51ff3d5ba703fc6029cba211f901f3d79c8a72d android.hardware.graphics.composer@2.1::IComposerClient
 1c98c2f5154345312ec054871792a2982ec5f3e2bc2abfb61a10c0b517978e20 android.hardware.graphics.composer@2.1::types
 a695898589e1ef15b2b2510f11edd6aafac9918d9cf8d74b4b6143b309dee542 android.hardware.graphics.mapper@2.0::IMapper
 28507d385a3dd224bf3c32f1bfd9f96092c4701b9c1cc66caa578fc3efc97877 android.hardware.graphics.mapper@2.0::types
@@ -189,4 +189,34 @@
 
 # ABI preserving changes to HALs released in Android O
 
+760485232f6cce07f8bb05e3475509956996b702f77415ee5bff05e2ec5a5bcc android.hardware.dumpstate@1.0::IDumpstateDevice
+1fecfa1609ff9d27ebf761a84b4336efa9d5dac5b241f19a6663f70d8db2c4b1 android.hardware.radio@1.0::IRadioResponse
 28e929b453df3d9f5060af2764e6cdb123ddb893e3e86923c877f6ff7e5f02c9 android.hardware.wifi@1.0::types
+
+# HALs released in Android O MR1
+
+4b65763663a94a3920134011691f8fbb42ccb7b7795589efddc049a9106047d6 android.hardware.oemlock@1.0::IOemLock
+e02cd3722cb5e8fa51179f5defacb4f7866f903c9c7c51dc01a3148473a71525 android.hardware.oemlock@1.0::types
+9f69e783fa2c482d90b2f799ddd33378a92d22a261983df6b492358e01f4d791 android.hardware.power@1.1::IPower
+574fd9758b7cab4922c72cc5a9f36d1cd48ffd3425fdd776426653280d3d4138 android.hardware.power@1.1::types
+f79edf50a378a9c9bb737f93f205dab91b4c63ea49723afc6f856c138203ea81 android.hardware.radio@1.1::IRadio
+fcc5c8c88b85a9f63fba67d9e674da466c72a98ca287f343fb5721d098713f86 android.hardware.radio@1.1::IRadioIndication
+50f27e8c7ec009d5d4418b2ce8392b940bbf052ecc1d7251285f332485a5ba4e android.hardware.radio@1.1::IRadioResponse
+be981148c95c0089f3ae92854f0e7ae999d308e927db3e065f12a4fabe07852f android.hardware.radio@1.1::ISap
+d8d6bf7b4d36c04ce587df75953c3f723cfbe71c896c1aa8ab6478eae126723d android.hardware.radio@1.1::types
+d8aae01606bfd34bf2fb9a59cadc016f46f318e56cddb8f15a945c5b3c1222bc android.hardware.tetheroffload.config@1.0::IOffloadConfig
+447b00306bc95a7aafec1d660f6f3e9f76ac8bc0353193435e5579ab833da619 android.hardware.tetheroffload.control@1.0::IOffloadControl
+07658829339d75962016e00ed81b005ad29fca7ac12ad3bc3ccd86b08d94c2d3 android.hardware.tetheroffload.control@1.0::ITetheringOffloadCallback
+0df5b0178af15c53cdce8fcf8ca14035e8e08db4fa76fdc12009ddbe0b53626b android.hardware.tetheroffload.control@1.0::types
+b30ef02ef26ff804e2f6acf1201bc141b59e134e6a0338562284491102cb13e3 android.hardware.usb@1.1::IUsb
+13a580e35af01270a1e9774177c51db51d8672e6139ba00851e654e68a4d7dff android.hardware.usb@1.1::IUsbCallback
+f0ed667288908c08fced570bd1f3c4a0f236aa927938e805f0d9fece525da81e android.hardware.usb@1.1::types
+f95a1e85612f2d0d616eacd2eb63c52d10dfa889f165df57697c30e1f47b4785 android.hardware.vibrator@1.1::IVibrator
+246fb9d9e2b4800aeb0adc3cdbaa15d0321ebab54b7bd1ab87da5b67c7b0b064 android.hardware.vibrator@1.1::types
+9bc43413b80cd0c59a022e93da1448dcb82dd10c6dd31932df4659e4bdcb1368 android.hardware.weaver@1.0::IWeaver
+7728b0393a2ed9796537d4165c7d95407e9d8cb447a647b545fdfe06a28689e7 android.hardware.weaver@1.0::types
+bb7c96762d0aa3ddb874c8815bacdd3cbc8fb87ea2f82b928bc29e24a3593055 android.hardware.wifi.offload@1.0::IOffload
+c3354ab0d381a236c12dc486ad4b6bec28c979d26748b4661f12ede36f392808 android.hardware.wifi.offload@1.0::IOffloadCallback
+b18caefefcc765092412285d776234fcf213b73bdf07ae1b67a5f71b2d2464e3 android.hardware.wifi.offload@1.0::types
+c26473e2e4a00af43e28a0ddf9002e5062a7d0940429e5efb6e5513a8abcb75c android.hardware.wifi@1.1::IWifi
+48adfb7259e3816a82a4c394ffaf56fb14628a542295b7a51f1311392d3f8769 android.hardware.wifi@1.1::IWifiChip
diff --git a/drm/1.0/Android.bp b/drm/1.0/Android.bp
index 7829de7..731f58f 100644
--- a/drm/1.0/Android.bp
+++ b/drm/1.0/Android.bp
@@ -89,3 +89,5 @@
         "libutils",
     ],
 }
+
+subdirs = ["default"]
diff --git a/drm/1.0/default/Android.bp b/drm/1.0/default/Android.bp
new file mode 100644
index 0000000..ed6bcde
--- /dev/null
+++ b/drm/1.0/default/Android.bp
@@ -0,0 +1,23 @@
+cc_library_static {
+    name: "android.hardware.drm@1.0-helper",
+    vendor_available: true,
+    defaults: ["hidl_defaults"],
+    srcs: [
+        "SharedLibrary.cpp",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wextra",
+        "-Wall",
+    ],
+    shared_libs: [
+        "liblog",
+    ],
+    header_libs: [
+        "libutils_headers",
+    ],
+    export_header_lib_headers: [
+        "libutils_headers",
+    ],
+    export_include_dirs : ["include"]
+}
diff --git a/drm/1.0/default/Android.mk b/drm/1.0/default/Android.mk
index 4c05da8..0cc6e71 100644
--- a/drm/1.0/default/Android.mk
+++ b/drm/1.0/default/Android.mk
@@ -36,6 +36,9 @@
   libutils \
   libbinder \
 
+LOCAL_STATIC_LIBRARIES := \
+  android.hardware.drm@1.0-helper \
+
 LOCAL_C_INCLUDES := \
   hardware/interfaces/drm
 
@@ -71,10 +74,12 @@
     libhidlmemory \
     libhidltransport \
     liblog \
-    libmediadrm \
     libstagefright_foundation \
     libutils \
 
+LOCAL_STATIC_LIBRARIES := \
+    android.hardware.drm@1.0-helper \
+
 LOCAL_C_INCLUDES := \
     frameworks/native/include \
     frameworks/av/include
diff --git a/drm/1.0/default/CryptoFactory.h b/drm/1.0/default/CryptoFactory.h
index 412b557..6b1d1ff 100644
--- a/drm/1.0/default/CryptoFactory.h
+++ b/drm/1.0/default/CryptoFactory.h
@@ -19,7 +19,7 @@
 #include <android/hardware/drm/1.0/ICryptoFactory.h>
 #include <hidl/Status.h>
 #include <media/hardware/CryptoAPI.h>
-#include <media/PluginLoader.h>
+#include <PluginLoader.h>
 #include <media/SharedLibrary.h>
 
 namespace android {
@@ -28,6 +28,7 @@
 namespace V1_0 {
 namespace implementation {
 
+using ::android::hardware::drm::V1_0::helper::PluginLoader;
 using ::android::hardware::drm::V1_0::ICryptoFactory;
 using ::android::hardware::drm::V1_0::ICryptoPlugin;
 using ::android::hardware::hidl_array;
@@ -51,7 +52,7 @@
             override;
 
 private:
-    android::PluginLoader<android::CryptoFactory> loader;
+    PluginLoader<android::CryptoFactory> loader;
 
     CryptoFactory(const CryptoFactory &) = delete;
     void operator=(const CryptoFactory &) = delete;
diff --git a/drm/1.0/default/DrmFactory.h b/drm/1.0/default/DrmFactory.h
index a008844..726bf97 100644
--- a/drm/1.0/default/DrmFactory.h
+++ b/drm/1.0/default/DrmFactory.h
@@ -19,7 +19,7 @@
 #include <android/hardware/drm/1.0/IDrmFactory.h>
 #include <hidl/Status.h>
 #include <media/drm/DrmAPI.h>
-#include <media/PluginLoader.h>
+#include <PluginLoader.h>
 #include <media/SharedLibrary.h>
 
 namespace android {
@@ -28,6 +28,7 @@
 namespace V1_0 {
 namespace implementation {
 
+using ::android::hardware::drm::V1_0::helper::PluginLoader;
 using ::android::hardware::drm::V1_0::IDrmFactory;
 using ::android::hardware::drm::V1_0::IDrmPlugin;
 using ::android::hardware::hidl_array;
@@ -53,7 +54,7 @@
             const hidl_string& appPackageName, createPlugin_cb _hidl_cb) override;
 
 private:
-    android::PluginLoader<android::DrmFactory> loader;
+    PluginLoader<android::DrmFactory> loader;
 
     DrmFactory(const DrmFactory &) = delete;
     void operator=(const DrmFactory &) = delete;
diff --git a/drm/1.0/vts/functional/shared_library.cpp b/drm/1.0/default/SharedLibrary.cpp
similarity index 82%
rename from drm/1.0/vts/functional/shared_library.cpp
rename to drm/1.0/default/SharedLibrary.cpp
index 6658150..0a942cd 100644
--- a/drm/1.0/vts/functional/shared_library.cpp
+++ b/drm/1.0/default/SharedLibrary.cpp
@@ -14,17 +14,19 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "drm-vts-shared-library"
+
+#include "SharedLibrary.h"
 
 #include <dlfcn.h>
-#include <shared_library.h>
 
-using std::string;
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_0 {
+namespace helper {
 
-namespace drm_vts {
-
-SharedLibrary::SharedLibrary(const string& path) {
-    mLibHandle = dlopen(path.c_str(), RTLD_NOW);
+SharedLibrary::SharedLibrary(const String8& path) {
+    mLibHandle = dlopen(path.string(), RTLD_NOW);
 }
 
 SharedLibrary::~SharedLibrary() {
@@ -53,4 +55,9 @@
     const char* error = dlerror();
     return error ? error : "No errors or unknown error";
 }
-};
+
+}
+}
+}
+}
+} // namespace android
diff --git a/drm/1.0/default/include/PluginLoader.h b/drm/1.0/default/include/PluginLoader.h
new file mode 100644
index 0000000..f387b3c
--- /dev/null
+++ b/drm/1.0/default/include/PluginLoader.h
@@ -0,0 +1,107 @@
+/**
+ * Copyright (C) 2016 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 PLUGIN_LOADER_H_
+#define PLUGIN_LOADER_H_
+
+#include "SharedLibrary.h"
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_0 {
+namespace helper {
+
+template <class T>
+class PluginLoader {
+
+  public:
+    PluginLoader(const char *dir, const char *entry) {
+        /**
+         * scan all plugins in the plugin directory and add them to the
+         * factories list.
+         */
+        String8 pluginDir(dir);
+
+        DIR* pDir = opendir(pluginDir.string());
+        if (pDir == NULL) {
+            ALOGE("Failed to find plugin directory %s", pluginDir.string());
+        } else {
+            struct dirent* pEntry;
+            while ((pEntry = readdir(pDir))) {
+                String8 file(pEntry->d_name);
+                if (file.getPathExtension() == ".so") {
+                    String8 path = pluginDir + "/" + pEntry->d_name;
+                    T *plugin = loadOne(path, entry);
+                    if (plugin) {
+                        factories.push(plugin);
+                    }
+                }
+            }
+            closedir(pDir);
+        }
+    }
+
+    ~PluginLoader() {
+        for (size_t i = 0; i < factories.size(); i++) {
+            delete factories[i];
+        }
+    }
+
+    T *getFactory(size_t i) const {
+        return factories[i];
+    }
+
+    size_t factoryCount() const {return factories.size();}
+
+  private:
+    T* loadOne(const char *path, const char *entry) {
+        sp<SharedLibrary> library = new SharedLibrary(String8(path));
+        if (!library.get()) {
+            ALOGE("Failed to open plugin library %s: %s", path,
+                    library->lastError());
+        } else {
+            typedef T *(*CreateFactoryFunc)();
+            CreateFactoryFunc createFactoryFunc =
+                    (CreateFactoryFunc)library->lookup(entry);
+            if (createFactoryFunc) {
+                ALOGV("Found plugin factory entry %s in %s", entry, path);
+                libraries.push(library);
+                T* result = createFactoryFunc();
+                return  result;
+           }
+        }
+        return NULL;
+    }
+
+    Vector<T *> factories;
+    Vector<sp<SharedLibrary> > libraries;
+
+    PluginLoader(const PluginLoader &) = delete;
+    void operator=(const PluginLoader &) = delete;
+};
+
+}
+}
+}
+}
+} // namespace android
+
+#endif // PLUGIN_LOADER_H_
+
diff --git a/drm/1.0/vts/functional/shared_library.h b/drm/1.0/default/include/SharedLibrary.h
similarity index 79%
rename from drm/1.0/vts/functional/shared_library.h
rename to drm/1.0/default/include/SharedLibrary.h
index 1f32243..8e174d0 100644
--- a/drm/1.0/vts/functional/shared_library.h
+++ b/drm/1.0/default/include/SharedLibrary.h
@@ -17,13 +17,18 @@
 #ifndef SHARED_LIBRARY_H_
 #define SHARED_LIBRARY_H_
 
-#include <string>
-#include <vector>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
 
-namespace drm_vts {
-class SharedLibrary {
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_0 {
+namespace helper {
+
+class SharedLibrary : public RefBase {
    public:
-    explicit SharedLibrary(const std::string& path);
+    explicit SharedLibrary(const String8& path);
     ~SharedLibrary();
 
     bool operator!() const;
@@ -36,6 +41,11 @@
     SharedLibrary(const SharedLibrary&) = delete;
     void operator=(const SharedLibrary&) = delete;
 };
-};
+
+}
+}
+}
+}
+}
 
 #endif  // SHARED_LIBRARY_H_
diff --git a/drm/1.0/vts/functional/Android.bp b/drm/1.0/vts/functional/Android.bp
index 43ea372..b45ce84 100644
--- a/drm/1.0/vts/functional/Android.bp
+++ b/drm/1.0/vts/functional/Android.bp
@@ -19,7 +19,6 @@
     srcs: [
         "drm_hal_clearkey_test.cpp",
         "drm_hal_vendor_test.cpp",
-        "shared_library.cpp",
         "vendor_modules.cpp"
         ],
     shared_libs: [
@@ -39,7 +38,8 @@
         "libutils",
     ],
     static_libs: [
-        "VtsHalHidlTargetTestBase"
+        "VtsHalHidlTargetTestBase",
+        "android.hardware.drm@1.0-helper",
     ],
     cflags: [
         "-O0",
diff --git a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
index e2c9cca..67b2c7d 100644
--- a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
+++ b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
@@ -128,7 +128,7 @@
         // Do the same for the crypto factory
         cryptoFactory = VtsTestBase::getService<ICryptoFactory>(name);
         if (cryptoFactory == nullptr) {
-            VtsTestBase::getService<ICryptoFactory>();
+            cryptoFactory = VtsTestBase::getService<ICryptoFactory>();
         }
         ASSERT_NE(cryptoFactory, nullptr);
 
diff --git a/drm/1.0/vts/functional/vendor_modules.cpp b/drm/1.0/vts/functional/vendor_modules.cpp
index 2bf0b28..98430f5 100644
--- a/drm/1.0/vts/functional/vendor_modules.cpp
+++ b/drm/1.0/vts/functional/vendor_modules.cpp
@@ -20,13 +20,16 @@
 #include <dlfcn.h>
 #include <log/log.h>
 #include <memory>
+#include <utils/String8.h>
+#include <SharedLibrary.h>
 
-#include "shared_library.h"
 #include "vendor_modules.h"
 
 using std::string;
 using std::vector;
 using std::unique_ptr;
+using ::android::String8;
+using ::android::hardware::drm::V1_0::helper::SharedLibrary;
 
 namespace drm_vts {
 void VendorModules::scanModules(const std::string &directory) {
@@ -48,7 +51,7 @@
 
 DrmHalVTSVendorModule* VendorModules::getModule(const string& path) {
     if (mOpenLibraries.find(path) == mOpenLibraries.end()) {
-        auto library = std::make_unique<SharedLibrary>(path);
+        auto library = std::make_unique<SharedLibrary>(String8(path.c_str()));
         if (!library) {
             ALOGE("failed to map shared library %s", path.c_str());
             return NULL;
diff --git a/drm/1.0/vts/functional/vendor_modules.h b/drm/1.0/vts/functional/vendor_modules.h
index ca538f6..8330b0a 100644
--- a/drm/1.0/vts/functional/vendor_modules.h
+++ b/drm/1.0/vts/functional/vendor_modules.h
@@ -18,8 +18,12 @@
 #define VENDOR_MODULES_H
 
 #include <map>
+#include <vector>
+#include <string>
 
-#include "shared_library.h"
+#include <SharedLibrary.h>
+
+using ::android::hardware::drm::V1_0::helper::SharedLibrary;
 
 class DrmHalVTSVendorModule;
 
diff --git a/dumpstate/1.0/IDumpstateDevice.hal b/dumpstate/1.0/IDumpstateDevice.hal
index 206c139..12a0db4 100644
--- a/dumpstate/1.0/IDumpstateDevice.hal
+++ b/dumpstate/1.0/IDumpstateDevice.hal
@@ -18,7 +18,14 @@
 
 interface IDumpstateDevice {
     /**
-     * Dumps device-specific state into the given file descriptor.
+     * Dump device-specific state into the given file descriptors.
+     *
+     * One file descriptor must be passed to this method but two may be passed:
+     * the first descriptor must be used to dump device-specific state in text
+     * format, the second descriptor is optional and may be used to dump
+     * device-specific state in binary format.
+     *
+     * @param h A native handle with one or two valid file descriptors.
      */
     dumpstateBoard(handle h);
 };
diff --git a/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp b/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
index 7ab4812..046bf56 100644
--- a/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
+++ b/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
@@ -59,6 +59,7 @@
 // Positive test: make sure dumpstateBoard() writes something to the FD.
 TEST_F(DumpstateHidlTest, TestOk) {
     FILE* file = tmpfile();
+
     ASSERT_NE(nullptr, file) << "Could not create temp file: " << strerror(errno);
 
     native_handle_t* handle = native_handle_create(1, 0);
@@ -80,6 +81,29 @@
     native_handle_delete(handle);
 }
 
+// Positive test: make sure dumpstateBoard() doesn't crash with two FDs.
+TEST_F(DumpstateHidlTest, TestHandleWithTwoFds) {
+    FILE* file1 = tmpfile();
+    FILE* file2 = tmpfile();
+
+    ASSERT_NE(nullptr, file1) << "Could not create temp file #1: " << strerror(errno);
+    ASSERT_NE(nullptr, file2) << "Could not create temp file #2: " << strerror(errno);
+
+    native_handle_t* handle = native_handle_create(2, 0);
+    ASSERT_NE(handle, nullptr) << "Could not create native_handle";
+    handle->data[0] = fileno(file1);
+    handle->data[1] = fileno(file2);
+
+    Return<void> status = dumpstate->dumpstateBoard(handle);
+    ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.description();
+
+    EXPECT_EQ(0, fclose(file1)) << errno;
+    EXPECT_EQ(0, fclose(file2)) << errno;
+
+    native_handle_close(handle);
+    native_handle_delete(handle);
+}
+
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
     int status = RUN_ALL_TESTS();
diff --git a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
index 61d23b0..91e75fe 100644
--- a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
+++ b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
@@ -49,6 +49,7 @@
     capabilities_called_count_ = 0;
     location_called_count_ = 0;
     info_called_count_ = 0;
+    notify_count_ = 0;
 
     gnss_hal_ = ::testing::VtsHalHidlTargetTestBase::getService<IGnss>();
     ASSERT_NE(gnss_hal_, nullptr);
@@ -93,12 +94,15 @@
     if (gnss_hal_ != nullptr) {
       gnss_hal_->cleanup();
     }
+    if (notify_count_ > 0) {
+        ALOGW("%d unprocessed callbacks discarded", notify_count_);
+    }
   }
 
   /* Used as a mechanism to inform the test that a callback has occurred */
   inline void notify() {
     std::unique_lock<std::mutex> lock(mtx_);
-    count++;
+    notify_count_++;
     cv_.notify_one();
   }
 
@@ -108,11 +112,11 @@
 
     std::cv_status status = std::cv_status::no_timeout;
     auto now = std::chrono::system_clock::now();
-    while (count == 0) {
-      status = cv_.wait_until(lock, now + std::chrono::seconds(timeoutSeconds));
-      if (status == std::cv_status::timeout) return status;
+    while (notify_count_ == 0) {
+        status = cv_.wait_until(lock, now + std::chrono::seconds(timeoutSeconds));
+        if (status == std::cv_status::timeout) return status;
     }
-    count--;
+    notify_count_--;
     return status;
   }
 
@@ -306,7 +310,7 @@
  private:
   std::mutex mtx_;
   std::condition_variable cv_;
-  int count;
+  int notify_count_;
 };
 
 /*
diff --git a/graphics/composer/2.1/IComposerClient.hal b/graphics/composer/2.1/IComposerClient.hal
index 85572d4..f2ff932 100644
--- a/graphics/composer/2.1/IComposerClient.hal
+++ b/graphics/composer/2.1/IComposerClient.hal
@@ -1117,6 +1117,7 @@
         VALIDATE_DISPLAY                   = 0x203 << OPCODE_SHIFT,
         ACCEPT_DISPLAY_CHANGES             = 0x204 << OPCODE_SHIFT,
         PRESENT_DISPLAY                    = 0x205 << OPCODE_SHIFT,
+        PRESENT_OR_VALIDATE_DISPLAY        = 0x206 << OPCODE_SHIFT,
 
         /** layer commands (VALIDATE_DISPLAY not required) */
         SET_LAYER_CURSOR_POSITION          = 0x300 << OPCODE_SHIFT,
@@ -1135,6 +1136,7 @@
         SET_LAYER_TRANSFORM                = 0x408 << OPCODE_SHIFT,
         SET_LAYER_VISIBLE_REGION           = 0x409 << OPCODE_SHIFT,
         SET_LAYER_Z_ORDER                  = 0x40a << OPCODE_SHIFT,
+        SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 0x40b << OPCODE_SHIFT,
 
         /** 0x800 - 0xfff are reserved for vendor extensions */
         /** 0x1000 - 0xffff are reserved */
diff --git a/graphics/composer/2.1/default/ComposerClient.cpp b/graphics/composer/2.1/default/ComposerClient.cpp
index ce4e17f..5a96e29 100644
--- a/graphics/composer/2.1/default/ComposerClient.cpp
+++ b/graphics/composer/2.1/default/ComposerClient.cpp
@@ -562,6 +562,8 @@
         return parseSetOutputBuffer(length);
     case IComposerClient::Command::VALIDATE_DISPLAY:
         return parseValidateDisplay(length);
+    case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
+        return parsePresentOrValidateDisplay(length);
     case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
         return parseAcceptDisplayChanges(length);
     case IComposerClient::Command::PRESENT_DISPLAY:
@@ -739,6 +741,47 @@
     return true;
 }
 
+bool ComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length)
+{
+    if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
+        return false;
+    }
+
+    // First try to Present as is.
+    int presentFence = -1;
+    std::vector<Layer> layers;
+    std::vector<int> fences;
+    auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
+    if (err == Error::NONE) {
+        mWriter.setPresentOrValidateResult(1);
+        mWriter.setPresentFence(presentFence);
+        mWriter.setReleaseFences(layers, fences);
+        return true;
+    }
+
+    // Present has failed. We need to fallback to validate
+    std::vector<Layer> changedLayers;
+    std::vector<IComposerClient::Composition> compositionTypes;
+    uint32_t displayRequestMask = 0x0;
+    std::vector<Layer> requestedLayers;
+    std::vector<uint32_t> requestMasks;
+
+    err = mHal.validateDisplay(mDisplay, &changedLayers,
+                               &compositionTypes, &displayRequestMask,
+                               &requestedLayers, &requestMasks);
+    if (err == Error::NONE) {
+        mWriter.setPresentOrValidateResult(0);
+        mWriter.setChangedCompositionTypes(changedLayers,
+                                           compositionTypes);
+        mWriter.setDisplayRequests(displayRequestMask,
+                                   requestedLayers, requestMasks);
+    } else {
+        mWriter.setError(getCommandLoc(), err);
+    }
+
+    return true;
+}
+
 bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
 {
     if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
diff --git a/graphics/composer/2.1/default/ComposerClient.h b/graphics/composer/2.1/default/ComposerClient.h
index 3d10f80..ee825fe 100644
--- a/graphics/composer/2.1/default/ComposerClient.h
+++ b/graphics/composer/2.1/default/ComposerClient.h
@@ -141,6 +141,7 @@
         bool parseSetClientTarget(uint16_t length);
         bool parseSetOutputBuffer(uint16_t length);
         bool parseValidateDisplay(uint16_t length);
+        bool parsePresentOrValidateDisplay(uint16_t length);
         bool parseAcceptDisplayChanges(uint16_t length);
         bool parsePresentDisplay(uint16_t length);
         bool parseSetLayerCursorPosition(uint16_t length);
diff --git a/graphics/composer/2.1/default/IComposerCommandBuffer.h b/graphics/composer/2.1/default/IComposerCommandBuffer.h
index fb78ef8..9ee5f4f 100644
--- a/graphics/composer/2.1/default/IComposerCommandBuffer.h
+++ b/graphics/composer/2.1/default/IComposerCommandBuffer.h
@@ -152,6 +152,13 @@
         endCommand();
     }
 
+    static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
+    void setPresentOrValidateResult(uint32_t  state) {
+       beginCommand(IComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT, kPresentOrValidateDisplayResultLength);
+       write(state);
+       endCommand();
+    }
+
     void setChangedCompositionTypes(const std::vector<Layer>& layers,
             const std::vector<IComposerClient::Composition>& types)
     {
@@ -284,6 +291,14 @@
         endCommand();
     }
 
+    static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
+    void presentOrvalidateDisplay()
+    {
+        beginCommand(IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY,
+                     kPresentOrValidateDisplayLength);
+        endCommand();
+    }
+
     static constexpr uint16_t kAcceptDisplayChangesLength = 0;
     void acceptDisplayChanges()
     {
diff --git a/ir/1.0/vts/functional/VtsHalIrV1_0TargetTest.cpp b/ir/1.0/vts/functional/VtsHalIrV1_0TargetTest.cpp
index 3dad3c1..a017404 100644
--- a/ir/1.0/vts/functional/VtsHalIrV1_0TargetTest.cpp
+++ b/ir/1.0/vts/functional/VtsHalIrV1_0TargetTest.cpp
@@ -59,7 +59,7 @@
     uint32_t len = 16;
     hidl_vec<int32_t> vec;
     vec.resize(len);
-    std::fill(vec.begin(), vec.end(), 1);
+    std::fill(vec.begin(), vec.end(), 1000);
     for (auto range = ranges.begin(); range != ranges.end(); range++) {
       EXPECT_TRUE(ir->transmit(range->min, vec));
       EXPECT_TRUE(ir->transmit(range->max, vec));
@@ -74,7 +74,6 @@
   vec.resize(len);
   std::fill(vec.begin(), vec.end(), 1);
   EXPECT_FALSE(ir->transmit(-1, vec));
-  EXPECT_FALSE(ir->transmit(0, vec));
 }
 
 int main(int argc, char **argv) {
diff --git a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
index 570e33f..78353ea 100644
--- a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -247,34 +247,47 @@
     return retval;
 }
 
-string rsa_key = hex2str("30820275020100300d06092a864886f70d01010105000482025f3082025b"
-                         "02010002818100c6095409047d8634812d5a218176e45c41d60a75b13901"
-                         "f234226cffe776521c5a77b9e389417b71c0b6a44d13afe4e4a2805d46c9"
-                         "da2935adb1ff0c1f24ea06e62b20d776430a4d435157233c6f916783c30e"
-                         "310fcbd89b85c2d56771169785ac12bca244abda72bfb19fc44d27c81e1d"
-                         "92de284f4061edfd99280745ea6d2502030100010281801be0f04d9cae37"
-                         "18691f035338308e91564b55899ffb5084d2460e6630257e05b3ceab0297"
-                         "2dfabcd6ce5f6ee2589eb67911ed0fac16e43a444b8c861e544a05933657"
-                         "72f8baf6b22fc9e3c5f1024b063ac080a7b2234cf8aee8f6c47bbf4fd3ac"
-                         "e7240290bef16c0b3f7f3cdd64ce3ab5912cf6e32f39ab188358afcccd80"
-                         "81024100e4b49ef50f765d3b24dde01aceaaf130f2c76670a91a61ae08af"
-                         "497b4a82be6dee8fcdd5e3f7ba1cfb1f0c926b88f88c92bfab137fba2285"
-                         "227b83c342ff7c55024100ddabb5839c4c7f6bf3d4183231f005b31aa58a"
-                         "ffdda5c79e4cce217f6bc930dbe563d480706c24e9ebfcab28a6cdefd324"
-                         "b77e1bf7251b709092c24ff501fd91024023d4340eda3445d8cd26c14411"
-                         "da6fdca63c1ccd4b80a98ad52b78cc8ad8beb2842c1d280405bc2f6c1bea"
-                         "214a1d742ab996b35b63a82a5e470fa88dbf823cdd02401b7b57449ad30d"
-                         "1518249a5f56bb98294d4b6ac12ffc86940497a5a5837a6cf946262b4945"
-                         "26d328c11e1126380fde04c24f916dec250892db09a6d77cdba351024077"
-                         "62cd8f4d050da56bd591adb515d24d7ccd32cca0d05f866d583514bd7324"
-                         "d5f33645e8ed8b4a1cb3cc4a1d67987399f2a09f5b3fb68c88d5e5d90ac3"
-                         "3492d6");
+string rsa_key = hex2str(
+    "30820275020100300d06092a864886f70d01010105000482025f3082025b"
+    "02010002818100c6095409047d8634812d5a218176e45c41d60a75b13901"
+    "f234226cffe776521c5a77b9e389417b71c0b6a44d13afe4e4a2805d46c9"
+    "da2935adb1ff0c1f24ea06e62b20d776430a4d435157233c6f916783c30e"
+    "310fcbd89b85c2d56771169785ac12bca244abda72bfb19fc44d27c81e1d"
+    "92de284f4061edfd99280745ea6d2502030100010281801be0f04d9cae37"
+    "18691f035338308e91564b55899ffb5084d2460e6630257e05b3ceab0297"
+    "2dfabcd6ce5f6ee2589eb67911ed0fac16e43a444b8c861e544a05933657"
+    "72f8baf6b22fc9e3c5f1024b063ac080a7b2234cf8aee8f6c47bbf4fd3ac"
+    "e7240290bef16c0b3f7f3cdd64ce3ab5912cf6e32f39ab188358afcccd80"
+    "81024100e4b49ef50f765d3b24dde01aceaaf130f2c76670a91a61ae08af"
+    "497b4a82be6dee8fcdd5e3f7ba1cfb1f0c926b88f88c92bfab137fba2285"
+    "227b83c342ff7c55024100ddabb5839c4c7f6bf3d4183231f005b31aa58a"
+    "ffdda5c79e4cce217f6bc930dbe563d480706c24e9ebfcab28a6cdefd324"
+    "b77e1bf7251b709092c24ff501fd91024023d4340eda3445d8cd26c14411"
+    "da6fdca63c1ccd4b80a98ad52b78cc8ad8beb2842c1d280405bc2f6c1bea"
+    "214a1d742ab996b35b63a82a5e470fa88dbf823cdd02401b7b57449ad30d"
+    "1518249a5f56bb98294d4b6ac12ffc86940497a5a5837a6cf946262b4945"
+    "26d328c11e1126380fde04c24f916dec250892db09a6d77cdba351024077"
+    "62cd8f4d050da56bd591adb515d24d7ccd32cca0d05f866d583514bd7324"
+    "d5f33645e8ed8b4a1cb3cc4a1d67987399f2a09f5b3fb68c88d5e5d90ac3"
+    "3492d6");
 
-string ec_key = hex2str("308187020100301306072a8648ce3d020106082a8648ce3d030107046d30"
-                        "6b0201010420737c2ecd7b8d1940bf2930aa9b4ed3ff941eed09366bc032"
-                        "99986481f3a4d859a14403420004bf85d7720d07c25461683bc648b4778a"
-                        "9a14dd8a024e3bdd8c7ddd9ab2b528bbc7aa1b51f14ebbbb0bd0ce21bcc4"
-                        "1c6eb00083cf3376d11fd44949e0b2183bfe");
+string ec_256_key = hex2str(
+    "308187020100301306072a8648ce3d020106082a8648ce3d030107046d30"
+    "6b0201010420737c2ecd7b8d1940bf2930aa9b4ed3ff941eed09366bc032"
+    "99986481f3a4d859a14403420004bf85d7720d07c25461683bc648b4778a"
+    "9a14dd8a024e3bdd8c7ddd9ab2b528bbc7aa1b51f14ebbbb0bd0ce21bcc4"
+    "1c6eb00083cf3376d11fd44949e0b2183bfe");
+
+string ec_521_key = hex2str(
+    "3081EE020100301006072A8648CE3D020106052B810400230481D63081D3"
+    "02010104420011458C586DB5DAA92AFAB03F4FE46AA9D9C3CE9A9B7A006A"
+    "8384BEC4C78E8E9D18D7D08B5BCFA0E53C75B064AD51C449BAE0258D54B9"
+    "4B1E885DED08ED4FB25CE9A1818903818600040149EC11C6DF0FA122C6A9"
+    "AFD9754A4FA9513A627CA329E349535A5629875A8ADFBE27DCB932C05198"
+    "6377108D054C28C6F39B6F2C9AF81802F9F326B842FF2E5F3C00AB7635CF"
+    "B36157FC0882D574A10D839C1A0C049DC5E0D775E2EE50671A208431BB45"
+    "E78E70BEFE930DB34818EE4D5C26259F5C6B8E28A652950F9F88D7B4B2C9"
+    "D9");
 
 struct RSA_Delete {
     void operator()(RSA* p) { RSA_free(p); }
@@ -408,7 +421,7 @@
   public:
     void TearDown() override {
         if (key_blob_.size()) {
-            EXPECT_EQ(ErrorCode::OK, DeleteKey());
+            CheckedDeleteKey();
         }
         AbortIfNeeded();
     }
@@ -540,6 +553,13 @@
         return error;
     }
 
+    void CheckedDeleteKey(HidlBuf* key_blob, bool keep_key_blob = false) {
+        auto rc = DeleteKey(key_blob, keep_key_blob);
+        EXPECT_TRUE(rc == ErrorCode::OK || rc == ErrorCode::UNIMPLEMENTED);
+    }
+
+    void CheckedDeleteKey() { CheckedDeleteKey(&key_blob_); }
+
     ErrorCode GetCharacteristics(const HidlBuf& key_blob, const HidlBuf& client_id,
                                  const HidlBuf& app_data, KeyCharacteristics* key_characteristics) {
         ErrorCode error = ErrorCode::UNKNOWN_ERROR;
@@ -760,7 +780,7 @@
                             KeyFormat::RAW, key));
         string signature = MacMessage(message, digest, expected_mac.size() * 8);
         EXPECT_EQ(expected_mac, signature) << "Test vector didn't match for digest " << (int)digest;
-        DeleteKey();
+        CheckedDeleteKey();
     }
 
     void CheckAesCtrTestVector(const string& key, const string& nonce, const string& message,
@@ -1107,7 +1127,7 @@
         EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size));
         EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 3));
 
-        EXPECT_EQ(ErrorCode::OK, DeleteKey(&key_blob));
+        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1152,7 +1172,7 @@
         EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
         EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size));
 
-        EXPECT_EQ(ErrorCode::OK, DeleteKey(&key_blob));
+        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1201,7 +1221,7 @@
         EXPECT_EQ(ErrorCode::OK,
                   GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(size).Digest(Digest::NONE)))
             << "Failed to generate size: " << size;
-        DeleteKey();
+        CheckedDeleteKey();
     }
 }
 
@@ -1217,7 +1237,7 @@
             ErrorCode::OK,
             GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(curve).Digest(Digest::SHA_2_512)))
             << "Failed to generate key on curve: " << curve;
-        DeleteKey();
+        CheckedDeleteKey();
     }
 }
 
@@ -1267,7 +1287,7 @@
             EXPECT_TRUE(softwareEnforced.Contains(TAG_KEY_SIZE, key_size));
         }
 
-        EXPECT_EQ(ErrorCode::OK, DeleteKey(&key_blob));
+        CheckedDeleteKey(&key_blob);
     }
 }
 
@@ -1295,7 +1315,7 @@
                                                      .HmacKey(key_size)
                                                      .Digest(Digest::SHA_2_256)
                                                      .Authorization(TAG_MIN_MAC_LENGTH, 256)));
-            DeleteKey();
+            CheckedDeleteKey();
         }
     }
 }
@@ -1327,7 +1347,7 @@
                                       .HmacKey(128)
                                       .Digest(Digest::SHA_2_256)
                                       .Authorization(TAG_MIN_MAC_LENGTH, min_mac_length)));
-            DeleteKey();
+            CheckedDeleteKey();
         }
     }
 }
@@ -1717,7 +1737,7 @@
             string message(1024, 'a');
             if (digest == Digest::NONE) message.resize(key_size / 8);
             SignMessage(message, AuthorizationSetBuilder().Digest(digest));
-            DeleteKey();
+            CheckedDeleteKey();
         }
     }
 }
@@ -1738,7 +1758,7 @@
 
         string message(1024, 'a');
         SignMessage(message, AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
-        DeleteKey();
+        CheckedDeleteKey();
     }
 }
 
@@ -1799,7 +1819,7 @@
         string signature = MacMessage(message, digest, 160);
         EXPECT_EQ(160U / 8U, signature.size())
             << "Failed to sign with HMAC key with digest " << digest;
-        DeleteKey();
+        CheckedDeleteKey();
     }
 }
 
@@ -2186,7 +2206,8 @@
                 << curve << ' ' << digest;
         }
 
-        ASSERT_EQ(ErrorCode::OK, DeleteKey());
+        auto rc = DeleteKey();
+        ASSERT_TRUE(rc == ErrorCode::OK || rc == ErrorCode::UNIMPLEMENTED);
     }
 }
 
@@ -2232,8 +2253,8 @@
     VerifyMessage(verification_key, message, signature,
                   AuthorizationSetBuilder().Digest(Digest::SHA1));
 
-    EXPECT_EQ(ErrorCode::OK, DeleteKey(&signing_key));
-    EXPECT_EQ(ErrorCode::OK, DeleteKey(&verification_key));
+    CheckedDeleteKey(&signing_key);
+    CheckedDeleteKey(&verification_key);
 }
 
 typedef KeymasterHidlTest ExportKeyTest;
@@ -2377,14 +2398,14 @@
 /*
  * ImportKeyTest.EcdsaSuccess
  *
- * Verifies that importing and using an ECDSA key pair works correctly.
+ * Verifies that importing and using an ECDSA P-256 key pair works correctly.
  */
 TEST_F(ImportKeyTest, EcdsaSuccess) {
     ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
                                            .Authorization(TAG_NO_AUTH_REQUIRED)
                                            .EcdsaSigningKey(256)
                                            .Digest(Digest::SHA_2_256),
-                                       KeyFormat::PKCS8, ec_key))
+                                       KeyFormat::PKCS8, ec_256_key))
         << "(Possibly b/33945114)";
 
     CheckKm0CryptoParam(TAG_ALGORITHM, Algorithm::EC);
@@ -2401,6 +2422,32 @@
 }
 
 /*
+ * ImportKeyTest.Ecdsa521Success
+ *
+ * Verifies that importing and using an ECDSA P-521 key pair works correctly.
+ */
+TEST_F(ImportKeyTest, Ecdsa521Success) {
+    ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
+                                           .Authorization(TAG_NO_AUTH_REQUIRED)
+                                           .EcdsaSigningKey(521)
+                                           .Digest(Digest::SHA_2_256),
+                                       KeyFormat::PKCS8, ec_521_key))
+        << "(Possibly b/33945114)";
+
+    CheckKm0CryptoParam(TAG_ALGORITHM, Algorithm::EC);
+    CheckKm0CryptoParam(TAG_KEY_SIZE, 521U);
+    CheckKm1CryptoParam(TAG_DIGEST, Digest::SHA_2_256);
+    CheckKm2CryptoParam(TAG_EC_CURVE, EcCurve::P_521);
+
+    CheckOrigin();
+
+    string message(32, 'a');
+    auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256);
+    string signature = SignMessage(message, params);
+    VerifyMessage(message, signature, params);
+}
+
+/*
  * ImportKeyTest.EcdsaSizeMismatch
  *
  * Verifies that importing an ECDSA key pair with a size that doesn't match the key fails in the
@@ -2411,7 +2458,7 @@
               ImportKey(AuthorizationSetBuilder()
                             .EcdsaSigningKey(224 /* Doesn't match key */)
                             .Digest(Digest::NONE),
-                        KeyFormat::PKCS8, ec_key));
+                        KeyFormat::PKCS8, ec_256_key));
 }
 
 /*
@@ -2430,7 +2477,7 @@
               ImportKey(AuthorizationSetBuilder()
                             .EcdsaSigningKey(EcCurve::P_224 /* Doesn't match key */)
                             .Digest(Digest::NONE),
-                        KeyFormat::PKCS8, ec_key))
+                        KeyFormat::PKCS8, ec_256_key))
         << "(Possibly b/36233241)";
 }
 
@@ -3481,14 +3528,14 @@
     string key = make_string(key_bytes);
     ASSERT_EQ(ErrorCode::OK, ImportKey(import_params, KeyFormat::RAW, key));
     string plaintext = DecryptMessage(ciphertext, params);
-    EXPECT_EQ(ErrorCode::OK, DeleteKey());
+    CheckedDeleteKey();
 
     // Corrupt key and attempt to decrypt
     key[0] = 0;
     ASSERT_EQ(ErrorCode::OK, ImportKey(import_params, KeyFormat::RAW, key));
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
     EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
-    EXPECT_EQ(ErrorCode::OK, DeleteKey());
+    CheckedDeleteKey();
 }
 
 /*
diff --git a/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp b/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
index c94fa4f..da49dfc 100644
--- a/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
+++ b/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
@@ -77,6 +77,7 @@
   if (fd1 < 0 || fd2 < 0) {
     // Files don't exist, so skip the rest of the test case
     SUCCEED();
+    return;
   }
 
   char old_governor[80];
diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal
index 35ab899..9f19169 100644
--- a/radio/1.0/IRadioResponse.hal
+++ b/radio/1.0/IRadioResponse.hal
@@ -28,6 +28,12 @@
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getIccCardStatusResponse(RadioResponseInfo info, CardStatus cardStatus);
 
@@ -39,6 +45,13 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyIccPinForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -50,6 +63,13 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT (PUK is invalid)
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyIccPukForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -61,6 +81,13 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyIccPin2ForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -71,6 +98,13 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT (PUK is invalid)
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyIccPuk2ForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -82,6 +116,13 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway changeIccPinForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -93,6 +134,13 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
      *   RadioError:PASSWORD_INCORRECT (old PIN2 is invalid)
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway changeIccPin2ForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -102,6 +150,7 @@
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:PASSWORD_INCORRECT (code is invalid)
      *   RadioError:NO_MEMORY
      *   RadioError:INVALID_SIM_STATE
@@ -109,6 +158,9 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway supplyNetworkDepersonalizationResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -124,6 +176,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCurrentCallsResponse(RadioResponseInfo info, vec<Call> calls);
 
@@ -152,6 +206,7 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:CANCELLED
      */
     oneway dialResponse(RadioResponseInfo info);
 
@@ -162,6 +217,13 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:SIM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getIMSIForAppResponse(RadioResponseInfo info, string imsi);
 
@@ -177,6 +239,9 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_CALL_ID
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway hangupConnectionResponse(RadioResponseInfo info);
 
@@ -196,6 +261,7 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
      */
     oneway hangupWaitingOrBackgroundResponse(RadioResponseInfo info);
 
@@ -215,6 +281,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway hangupForegroundResumeBackgroundResponse(RadioResponseInfo info);
 
@@ -235,6 +303,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway switchWaitingOrHoldingAndActiveResponse(RadioResponseInfo info);
 
@@ -254,6 +324,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway conferenceResponse(RadioResponseInfo info);
 
@@ -274,6 +346,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway rejectCallResponse(RadioResponseInfo info);
 
@@ -322,6 +396,9 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getLastCallFailCauseResponse(RadioResponseInfo info,
             LastCallFailCauseInfo failCauseinfo);
@@ -339,6 +416,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getSignalStrengthResponse(RadioResponseInfo info, SignalStrength sigStrength);
 
@@ -350,6 +429,11 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getVoiceRegistrationStateResponse(RadioResponseInfo info,
             VoiceRegStateResult voiceRegResponse);
@@ -368,6 +452,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getDataRegistrationStateResponse(RadioResponseInfo info,
             DataRegStateResult dataRegResponse);
@@ -385,6 +471,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getOperatorResponse(RadioResponseInfo info, string longName, string shortName,
             string numeric);
@@ -406,6 +494,8 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setRadioPowerResponse(RadioResponseInfo info);
 
@@ -423,6 +513,7 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway sendDtmfResponse(RadioResponseInfo info);
@@ -452,6 +543,8 @@
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -481,6 +574,8 @@
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendSMSExpectMoreResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -497,7 +592,10 @@
      *   RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setupDataCallResponse(RadioResponseInfo info, SetupDataCallResult dcResponse);
 
@@ -510,6 +608,13 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_PIN2
      *   RadioError:SIM_PUK2
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:SIM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccIOForAppResponse(RadioResponseInfo info, IccIoResult iccIo);
 
@@ -534,6 +639,8 @@
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendUssdResponse(RadioResponseInfo info);
 
@@ -553,6 +660,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway cancelPendingUssdResponse(RadioResponseInfo info);
 
@@ -574,6 +683,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getClirResponse(RadioResponseInfo info, int32_t n, int32_t m);
 
@@ -591,6 +702,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setClirResponse(RadioResponseInfo info);
 
@@ -620,6 +733,8 @@
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SYSTEM_ERR
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCallForwardStatusResponse(RadioResponseInfo info,
             vec<CallForwardInfo> callForwardInfos);
@@ -642,6 +757,8 @@
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setCallForwardResponse(RadioResponseInfo info);
 
@@ -669,6 +786,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCallWaitingResponse(RadioResponseInfo info, bool enable, int32_t serviceClass);
 
@@ -690,6 +809,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setCallWaitingResponse(RadioResponseInfo info);
 
@@ -699,6 +820,11 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway acknowledgeLastIncomingGsmSmsResponse(RadioResponseInfo info);
 
@@ -717,6 +843,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway acceptCallResponse(RadioResponseInfo info);
 
@@ -730,6 +858,10 @@
      *   RadioError:INVALID_STATE
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway deactivateDataCallResponse(RadioResponseInfo info);
 
@@ -752,6 +884,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getFacilityLockForAppResponse(RadioResponseInfo info, int32_t response);
 
@@ -774,6 +908,8 @@
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setFacilityLockForAppResponse(RadioResponseInfo info, int32_t retry);
 
@@ -793,6 +929,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setBarringPasswordResponse(RadioResponseInfo info);
 
@@ -809,6 +947,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getNetworkSelectionModeResponse(RadioResponseInfo info, bool manual);
 
@@ -826,6 +966,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *
      * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and
      * no retries needed, such as illegal SIM or ME.
@@ -847,6 +989,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *
      * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and
      * no retries needed, such as illegal SIM or ME.
@@ -869,6 +1013,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:CANCELLED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:INTERNAL_ERR
      */
     oneway getAvailableNetworksResponse(RadioResponseInfo info,
             vec<OperatorInfo> networkInfos);
@@ -888,6 +1034,7 @@
      *   RadioError:INVALID_CALL_ID
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway startDtmfResponse(RadioResponseInfo info);
@@ -907,6 +1054,7 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_CALL_ID
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway stopDtmfResponse(RadioResponseInfo info);
@@ -925,6 +1073,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getBasebandVersionResponse(RadioResponseInfo info, string version);
 
@@ -945,6 +1095,7 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:CANCELLED
      */
     oneway separateConnectionResponse(RadioResponseInfo info);
 
@@ -960,6 +1111,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setMuteResponse(RadioResponseInfo info);
 
@@ -979,6 +1132,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getMuteResponse(RadioResponseInfo info, bool enable);
 
@@ -996,6 +1151,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getClipResponse(RadioResponseInfo info, ClipStatus status);
 
@@ -1006,6 +1163,11 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getDataCallListResponse(RadioResponseInfo info, vec<SetupDataCallResult> dcResponse);
 
@@ -1022,6 +1184,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setSuppServiceNotificationsResponse(RadioResponseInfo info);
 
@@ -1031,6 +1195,7 @@
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_FULL
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SMS_FORMAT
@@ -1045,6 +1210,8 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway writeSmsToSimResponse(RadioResponseInfo info, int32_t index);
 
@@ -1053,6 +1220,8 @@
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:SIM_FULL
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
@@ -1061,6 +1230,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway deleteSmsOnSimResponse(RadioResponseInfo info);
@@ -1078,6 +1249,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setBandModeResponse(RadioResponseInfo info);
 
@@ -1094,6 +1267,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getAvailableBandModesResponse(RadioResponseInfo info, vec<RadioBandMode> bandModes);
 
@@ -1107,6 +1282,13 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_BUSY
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:MODEM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway sendEnvelopeResponse(RadioResponseInfo info, string commandResponse);
 
@@ -1118,6 +1300,12 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway sendTerminalResponseToSimResponse(RadioResponseInfo info);
 
@@ -1126,11 +1314,15 @@
      *
      * Valid errors returned:
      *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:NO_MEMORY
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway handleStkCallSetupRequestFromSimResponse(RadioResponseInfo info);
 
@@ -1151,6 +1343,8 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway explicitCallTransferResponse(RadioResponseInfo info);
 
@@ -1168,6 +1362,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setPreferredNetworkTypeResponse(RadioResponseInfo info);
 
@@ -1184,6 +1380,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getPreferredNetworkTypeResponse(RadioResponseInfo info,
             PreferredNetworkType nwType);
@@ -1202,6 +1400,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NO_NETWORK_FOUND
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getNeighboringCidsResponse(RadioResponseInfo info, vec<NeighboringCell> cells);
 
@@ -1217,6 +1417,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setLocationUpdatesResponse(RadioResponseInfo info);
 
@@ -1228,6 +1430,11 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_ABSENT
      *   RadioError:SUBSCRIPTION_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway setCdmaSubscriptionSourceResponse(RadioResponseInfo info);
 
@@ -1244,6 +1451,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setCdmaRoamingPreferenceResponse(RadioResponseInfo info);
 
@@ -1260,6 +1469,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCdmaRoamingPreferenceResponse(RadioResponseInfo info, CdmaRoamingType type);
 
@@ -1275,6 +1486,8 @@
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setTTYModeResponse(RadioResponseInfo info);
 
@@ -1291,6 +1504,8 @@
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getTTYModeResponse(RadioResponseInfo info, TtyMode mode);
 
@@ -1307,6 +1522,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_CALL_ID
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setPreferredVoicePrivacyResponse(RadioResponseInfo info);
 
@@ -1324,6 +1541,8 @@
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getPreferredVoicePrivacyResponse(RadioResponseInfo info, bool enable);
 
@@ -1344,6 +1563,9 @@
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:MODE_NOT_SUPPORTED
      */
     oneway sendCDMAFeatureCodeResponse(RadioResponseInfo info);
 
@@ -1361,6 +1583,9 @@
      *   RadioError:INVALID_CALL_ID
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      *   RadioError:MODE_NOT_SUPPORTED
      */
     oneway sendBurstDtmfResponse(RadioResponseInfo info);
@@ -1391,6 +1616,8 @@
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:ENCODING_ERR
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendCdmaSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -1413,6 +1640,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway acknowledgeLastIncomingCdmaSmsResponse(RadioResponseInfo info);
 
@@ -1432,6 +1661,9 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway getGsmBroadcastConfigResponse(RadioResponseInfo info,
             vec<GsmBroadcastSmsConfigInfo> configs);
@@ -1450,6 +1682,9 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway setGsmBroadcastConfigResponse(RadioResponseInfo info);
 
@@ -1468,6 +1703,9 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway setGsmBroadcastActivationResponse(RadioResponseInfo info);
 
@@ -1487,6 +1725,9 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway getCdmaBroadcastConfigResponse(RadioResponseInfo info,
             vec<CdmaBroadcastSmsConfigInfo> configs);
@@ -1505,6 +1746,9 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway setCdmaBroadcastConfigResponse(RadioResponseInfo info);
 
@@ -1523,6 +1767,9 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway setCdmaBroadcastActivationResponse(RadioResponseInfo info);
 
@@ -1547,6 +1794,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCDMASubscriptionResponse(RadioResponseInfo info, string mdn, string hSid,
             string hNid, string min, string prl);
@@ -1572,6 +1821,9 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
      */
     oneway writeSmsToRuimResponse(RadioResponseInfo info, uint32_t index);
 
@@ -1588,6 +1840,9 @@
      *   RadioError:NO_SUCH_ENTRY
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
     oneway deleteSmsOnRuimResponse(RadioResponseInfo info);
@@ -1608,6 +1863,9 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      *
      * If a empty string value is returned for any of the device id, it means that there was error
      * accessing the device.
@@ -1629,6 +1887,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway exitEmergencyCallbackModeResponse(RadioResponseInfo info);
 
@@ -1649,6 +1909,8 @@
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getSmscAddressResponse(RadioResponseInfo info, string smsc);
 
@@ -1668,6 +1930,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setSmscAddressResponse(RadioResponseInfo info);
 
@@ -1685,6 +1949,8 @@
      *   RadioError:INVALID_STATE
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway reportSmsMemoryStatusResponse(RadioResponseInfo info);
 
@@ -1694,6 +1960,11 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway reportStkServiceIsRunningResponse(RadioResponseInfo info);
 
@@ -1705,6 +1976,11 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SUBSCRIPTION_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getCdmaSubscriptionSourceResponse(RadioResponseInfo info, CdmaSubscriptionSource source);
 
@@ -1715,6 +1991,13 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway requestIsimAuthenticationResponse(RadioResponseInfo info, string response);
 
@@ -1724,6 +2007,11 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway acknowledgeIncomingGsmSmsWithPduResponse(RadioResponseInfo info);
 
@@ -1736,6 +2024,11 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_BUSY
      *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway sendEnvelopeWithStatusResponse(RadioResponseInfo info, IccIoResult iccIo);
 
@@ -1746,6 +2039,11 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getVoiceRadioTechnologyResponse(RadioResponseInfo info, RadioTechnology rat);
 
@@ -1762,6 +2060,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NO_NETWORK_FOUND
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getCellInfoListResponse(RadioResponseInfo info, vec<CellInfo> cellInfo);
 
@@ -1775,6 +2075,9 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway setCellInfoListRateResponse(RadioResponseInfo info);
 
@@ -1792,6 +2095,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NOT_PROVISIONED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setInitialAttachApnResponse(RadioResponseInfo info);
 
@@ -1804,12 +2109,12 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:NO_MEMORY
      *   RadioError:INTERNAL_ERR
-     *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
-     *   RadioError:MODEM_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getImsRegistrationStateResponse(RadioResponseInfo info, bool isRegistered,
             RadioTechnologyFamily ratFamily);
@@ -1837,6 +2142,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NETWORK_NOT_READY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendImsSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -1847,6 +2154,11 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccTransmitApduBasicChannelResponse(RadioResponseInfo info, IccIoResult result);
 
@@ -1861,6 +2173,14 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:MISSING_RESOURCE
      *   RadioError:NO_SUCH_ELEMENT
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:SIM_ERR
+     *   RadioError:INVALID_SIM_STATE
+     *   RadioError:MISSING_RESOURCE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccOpenLogicalChannelResponse(RadioResponseInfo info, int32_t channelId,
             vec<int8_t> selectResponse);
@@ -1871,6 +2191,11 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccCloseLogicalChannelResponse(RadioResponseInfo info);
 
@@ -1881,6 +2206,11 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway iccTransmitApduLogicalChannelResponse(RadioResponseInfo info, IccIoResult result);
 
@@ -1891,6 +2221,7 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway nvReadItemResponse(RadioResponseInfo info, string result);
 
@@ -1900,6 +2231,7 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway nvWriteItemResponse(RadioResponseInfo info);
 
@@ -1909,6 +2241,7 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway nvWriteCdmaPrlResponse(RadioResponseInfo info);
 
@@ -1918,6 +2251,7 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway nvResetConfigResponse(RadioResponseInfo info);
 
@@ -1934,6 +2268,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setUiccSubscriptionResponse(RadioResponseInfo info);
 
@@ -1950,6 +2286,9 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:DEVICE_IN_USE
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway setDataAllowedResponse(RadioResponseInfo info);
 
@@ -1960,6 +2299,7 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getHardwareConfigResponse(RadioResponseInfo info, vec<HardwareConfig> config);
 
@@ -1970,6 +2310,14 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:SIM_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway requestIccSimAuthenticationResponse(RadioResponseInfo info, IccIoResult result);
 
@@ -1980,6 +2328,11 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SUBSCRIPTION_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway setDataProfileResponse(RadioResponseInfo info);
 
@@ -1994,6 +2347,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway requestShutdownResponse(RadioResponseInfo info);
 
@@ -2007,6 +2362,10 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway getRadioCapabilityResponse(RadioResponseInfo info, RadioCapability rc);
 
@@ -2026,6 +2385,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_STATE
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setRadioCapabilityResponse(RadioResponseInfo info, RadioCapability rc);
 
@@ -2039,6 +2400,9 @@
      *   RadioError:LCE_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway startLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo);
 
@@ -2050,6 +2414,11 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:LCE_NOT_SUPPORTED
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway stopLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo);
 
@@ -2062,6 +2431,10 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:LCE_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway pullLceDataResponse(RadioResponseInfo info, LceDataInfo lceInfo);
 
@@ -2077,6 +2450,9 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway getModemActivityInfoResponse(RadioResponseInfo info, ActivityStatsInfo activityInfo);
 
@@ -2122,6 +2498,8 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway sendDeviceStateResponse(RadioResponseInfo info);
 
@@ -2136,6 +2514,8 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setIndicationFilterResponse(RadioResponseInfo info);
 
@@ -2147,6 +2527,10 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
      */
     oneway setSimCardPowerResponse(RadioResponseInfo info);
 
diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp
index 5403971..8cd823e 100644
--- a/radio/1.0/vts/functional/Android.bp
+++ b/radio/1.0/vts/functional/Android.bp
@@ -70,3 +70,38 @@
         "-g",
     ],
 }
+
+cc_library_static {
+    name: "RadioHidlHalUtilsBase",
+    srcs : [
+        "radio_hidl_hal_test.cpp",
+        "radio_response.cpp"
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.radio@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
+
+cc_library_static {
+    name: "RadioVtsTestUtilBase",
+    srcs : [
+        "vts_test_util.cpp"
+    ],
+}
+
+cc_library_headers {
+    name: "radio.util.header@1.0",
+    export_include_dirs: ["."],
+}
\ No newline at end of file
diff --git a/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp b/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp
index 59881ef..3448494 100644
--- a/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp
+++ b/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 int main(int argc, char** argv) {
     ::testing::AddGlobalTestEnvironment(new RadioHidlEnvironment);
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
index 14d14d4..a81861d 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 using namespace ::android::hardware::radio::V1_0;
 
@@ -123,7 +123,8 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -140,7 +141,7 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(CheckGeneralError());
+        ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -159,7 +160,8 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
index 108676b..35d97ee 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 using namespace ::android::hardware::radio::V1_0;
 
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 4841185..9e003e2 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 /*
  * Test IRadio.getIccCardStatus() for the response returned.
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
index 16465c7..c1834c5 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 using namespace ::android::hardware::radio::V1_0;
 
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index 69da6b2..70d6187 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 /*
  * Test IRadio.getSignalStrength() for the response returned.
@@ -184,7 +184,7 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+        ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -216,7 +216,7 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+        ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -705,7 +705,8 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE || CheckOEMError() ||
-                    radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+                    radioRsp->rspInfo.error == RadioError::INTERNAL_ERR ||
+                    radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -745,7 +746,7 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE || CheckGeneralError());
   }
 
   /* Reset back to no carrier restriction */
@@ -759,7 +760,7 @@
   EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
   if (cardStatus.cardState == CardState::ABSENT) {
-      ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+      ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE || CheckGeneralError());
   }
 }
 
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 9aa7663..271a23a 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 using namespace ::android::hardware::radio::V1_0;
 
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
index 6ff0330..9e51df4 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 using namespace ::android::hardware::radio::V1_0;
 
@@ -37,7 +37,8 @@
         std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::NONE);
+                    radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
     }
 
     // Test with sending random string
@@ -54,7 +55,8 @@
         std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::NONE);
+                    radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
     }
 }
 
@@ -153,7 +155,8 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
     }
 
     // Test with sending random string
@@ -168,6 +171,7 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
     }
 }
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
index b957c6e..2fa2827 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 void RadioHidlTest::SetUp() {
     radio =
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_utils.h b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
similarity index 99%
rename from radio/1.0/vts/functional/radio_hidl_hal_utils.h
rename to radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
index a0d7f70..c126da4 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
@@ -26,7 +26,7 @@
 #include <android/hardware/radio/1.0/IRadioResponse.h>
 #include <android/hardware/radio/1.0/types.h>
 
-#include <vts_test_util.h>
+#include "vts_test_util.h"
 
 using ::android::hardware::radio::V1_0::ActivityStatsInfo;
 using ::android::hardware::radio::V1_0::AppType;
@@ -90,7 +90,7 @@
 
 /* Callback class for radio response */
 class RadioResponse : public IRadioResponse {
-   private:
+   protected:
     RadioHidlTest& parent;
 
    public:
@@ -442,7 +442,7 @@
 
 // The main test class for Radio HIDL.
 class RadioHidlTest : public ::testing::VtsHalHidlTargetTestBase {
-   private:
+   protected:
     std::mutex mtx;
     std::condition_variable cv;
     int count;
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp b/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
index 8fe04fd..6655fc7 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 /*
  * Test IRadio.getCurrentCalls() for the response returned.
@@ -214,7 +214,8 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::INVALID_STATE ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
+                    radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -370,7 +371,8 @@
                     radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::INVALID_CALL_ID ||
                     radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
+                    radioRsp->rspInfo.error == RadioError::MODE_NOT_SUPPORTED);
     }
 }
 
diff --git a/radio/1.0/vts/functional/radio_response.cpp b/radio/1.0/vts/functional/radio_response.cpp
index ef887eb..434d488 100644
--- a/radio/1.0/vts/functional/radio_response.cpp
+++ b/radio/1.0/vts/functional/radio_response.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <radio_hidl_hal_utils.h>
+#include <radio_hidl_hal_utils_v1_0.h>
 
 CardStatus cardStatus;
 
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_utils.h b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
index fe93a4d..7126b06 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
@@ -25,7 +25,7 @@
 #include <android/hardware/radio/1.0/ISapCallback.h>
 #include <android/hardware/radio/1.0/types.h>
 
-#include <vts_test_util.h>
+#include "vts_test_util.h"
 
 using namespace ::android::hardware::radio::V1_0;
 
diff --git a/radio/1.1/Android.bp b/radio/1.1/Android.bp
index 3583159..3a3f639 100644
--- a/radio/1.1/Android.bp
+++ b/radio/1.1/Android.bp
@@ -7,6 +7,7 @@
         "IRadio.hal",
         "IRadioIndication.hal",
         "IRadioResponse.hal",
+        "ISap.hal",
     ],
 }
 
@@ -22,6 +23,7 @@
         "android/hardware/radio/1.1/RadioAll.cpp",
         "android/hardware/radio/1.1/RadioIndicationAll.cpp",
         "android/hardware/radio/1.1/RadioResponseAll.cpp",
+        "android/hardware/radio/1.1/SapAll.cpp",
     ],
 }
 
@@ -50,6 +52,11 @@
         "android/hardware/radio/1.1/BnHwRadioResponse.h",
         "android/hardware/radio/1.1/BpHwRadioResponse.h",
         "android/hardware/radio/1.1/BsRadioResponse.h",
+        "android/hardware/radio/1.1/ISap.h",
+        "android/hardware/radio/1.1/IHwSap.h",
+        "android/hardware/radio/1.1/BnHwSap.h",
+        "android/hardware/radio/1.1/BpHwSap.h",
+        "android/hardware/radio/1.1/BsSap.h",
     ],
 }
 
diff --git a/radio/1.1/Android.mk b/radio/1.1/Android.mk
index 305b661..b8aeb4f 100644
--- a/radio/1.1/Android.mk
+++ b/radio/1.1/Android.mk
@@ -75,6 +75,101 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (ImsiEncryptionInfo)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/ImsiEncryptionInfo.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.ImsiEncryptionInfo
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (KeepaliveRequest)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/KeepaliveRequest.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.KeepaliveRequest
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (KeepaliveStatus)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/KeepaliveStatus.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.KeepaliveStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (KeepaliveStatusCode)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/KeepaliveStatusCode.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.KeepaliveStatusCode
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (KeepaliveType)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/KeepaliveType.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.KeepaliveType
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (NetworkScanRequest)
 #
 GEN := $(intermediates)/android/hardware/radio/V1_1/NetworkScanRequest.java
@@ -256,6 +351,8 @@
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IRadioResponse.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
 $(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
 $(GEN): PRIVATE_CUSTOM_TOOL = \
         $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
@@ -267,6 +364,25 @@
 $(GEN): $(LOCAL_PATH)/IRadioResponse.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ISap.hal
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/ISap.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISap.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.radio@1.1::ISap
+
+$(GEN): $(LOCAL_PATH)/ISap.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
 include $(BUILD_JAVA_LIBRARY)
 
 
@@ -343,6 +459,101 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (ImsiEncryptionInfo)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/ImsiEncryptionInfo.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.ImsiEncryptionInfo
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (KeepaliveRequest)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/KeepaliveRequest.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.KeepaliveRequest
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (KeepaliveStatus)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/KeepaliveStatus.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.KeepaliveStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (KeepaliveStatusCode)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/KeepaliveStatusCode.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.KeepaliveStatusCode
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (KeepaliveType)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/KeepaliveType.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.radio@1.1::types.KeepaliveType
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (NetworkScanRequest)
 #
 GEN := $(intermediates)/android/hardware/radio/V1_1/NetworkScanRequest.java
@@ -524,6 +735,8 @@
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IRadioResponse.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
 $(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
 $(GEN): PRIVATE_CUSTOM_TOOL = \
         $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
@@ -535,6 +748,25 @@
 $(GEN): $(LOCAL_PATH)/IRadioResponse.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ISap.hal
+#
+GEN := $(intermediates)/android/hardware/radio/V1_1/ISap.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISap.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.radio@1.1::ISap
+
+$(GEN): $(LOCAL_PATH)/ISap.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 
diff --git a/radio/1.1/IRadio.hal b/radio/1.1/IRadio.hal
index b3e21e7..22d27d4 100644
--- a/radio/1.1/IRadio.hal
+++ b/radio/1.1/IRadio.hal
@@ -34,23 +34,13 @@
      * switch and everytime the framework receives a new certificate.
      *
      * @param serial Serial number of request.
-     * @param carrierKey Carrier specific key to be used for encryption. It must
-     *        be opaque to the framework. This is the byte-stream representation
-     *        of the key. This is an external encoded form for the key used when
-     *        a standard representation of the key is needed outside the Java
-     *        Virtual Machine, as when transmitting the key to some other party.
-     *        The key is encoded according to a standard format
-     *        (such as X.509 SubjectPublicKeyInfo or PKCS#8), and is returned using
-     *        the getEncoded method.
-     * @param keyIdentifier This is an opaque value we're given by the carrier
-     *        and is returned to the carrier. This is used by the server to
-     *        help it locate the private key to decrypt the permanent identity.
+     * @param message ImsiEncryptionInfo as defined in types.hal.
+     *
      *
      * Response callback is
      * IRadioResponse.setCarrierInfoForImsiEncryptionResponse()
      */
-     oneway setCarrierInfoForImsiEncryption(int32_t serial, vec<uint8_t> carrierKey,
-             string keyIdentifier);
+     oneway setCarrierInfoForImsiEncryption(int32_t serial, ImsiEncryptionInfo imsiEncryptionInfo);
 
     /**
      * Set SIM card power state.
@@ -99,4 +89,24 @@
      * Response function is IRadioResponse.stopNetworkScanResponse()
      */
     oneway stopNetworkScan(int32_t serial);
+
+    /**
+     * Start a Keepalive session (for IPsec)
+     *
+     * @param serial Serial number of request.
+     * @param keepalive A request structure containing all necessary info to describe a keepalive
+     *
+     * Response function is IRadioResponse.startKeepaliveResponse()
+     */
+    oneway startKeepalive(int32_t serial, KeepaliveRequest keepalive);
+
+    /**
+     * Stop an ongoing Keepalive session (for IPsec)
+     *
+     * @param serial Serial number of request.
+     * @param sessionHandle The handle that was provided by IRadioResponse.startKeepaliveResponse
+     *
+     * Response function is IRadioResponse.stopKeepaliveResponse()
+     */
+    oneway stopKeepalive(int32_t serial, int32_t sessionHandle);
 };
diff --git a/radio/1.1/IRadioIndication.hal b/radio/1.1/IRadioIndication.hal
index 27b6ec2..a0ad9b2 100644
--- a/radio/1.1/IRadioIndication.hal
+++ b/radio/1.1/IRadioIndication.hal
@@ -39,4 +39,15 @@
      * @param result Network scan result as NetworkScanResult defined in types.hal
      */
     oneway networkScanResult(RadioIndicationType type, NetworkScanResult result);
-};
\ No newline at end of file
+
+    /**
+     * Indicates a status update for a particular Keepalive session. This must include
+     * a handle for a previous session and should include a status update regarding the
+     * state of a keepalive. Unsolicited keepalive status reports should never be
+     * PENDING as unsolicited status should only be sent when known.
+     *
+     * @param type Type of radio indication
+     * @param status Status information for a Keepalive session
+     */
+    oneway keepaliveStatus(RadioIndicationType type, KeepaliveStatus status);
+};
diff --git a/radio/1.1/IRadioResponse.hal b/radio/1.1/IRadioResponse.hal
index 7415252..4e7bf43 100644
--- a/radio/1.1/IRadioResponse.hal
+++ b/radio/1.1/IRadioResponse.hal
@@ -71,4 +71,26 @@
      *   RadioError:MODEM_ERR
      */
     oneway stopNetworkScanResponse(RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     * @param status Status object containing a new handle and a current status. The
+     * status returned here may be PENDING to indicate that the radio has not yet
+     * processed the keepalive request.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:NO_RESOURCES
+     *   RadioError:INVALID_ARGUMENTS
+     */
+    oneway startKeepaliveResponse(RadioResponseInfo info, KeepaliveStatus status);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:INVALID_ARGUMENTS
+     */
+    oneway stopKeepaliveResponse(RadioResponseInfo info);
 };
diff --git a/configstore/1.1/ISurfaceFlingerConfigs.hal b/radio/1.1/ISap.hal
similarity index 61%
rename from configstore/1.1/ISurfaceFlingerConfigs.hal
rename to radio/1.1/ISap.hal
index 5eacbe0..edcf176 100644
--- a/configstore/1.1/ISurfaceFlingerConfigs.hal
+++ b/radio/1.1/ISap.hal
@@ -1,11 +1,11 @@
 /*
  * Copyright (C) 2017 The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.1 (the "License");
+ * 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.1
+ *      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,
@@ -13,13 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.hardware.configstore@1.1;
 
-import @1.0::ISurfaceFlingerConfigs;
+package android.hardware.radio@1.1;
 
-/**
- * New revision of ISurfaceFlingerConfigs
- */
+import @1.0::ISap;
 
-interface ISurfaceFlingerConfigs extends @1.0::ISurfaceFlingerConfigs {
+interface ISap extends @1.0::ISap {
+    /**
+     * Empty top level interface.
+     */
 };
diff --git a/radio/1.1/types.hal b/radio/1.1/types.hal
index 245d96c..93d5d44 100644
--- a/radio/1.1/types.hal
+++ b/radio/1.1/types.hal
@@ -132,6 +132,19 @@
     COMPLETE = 2,                           // The result contains the last part of the scan results
 };
 
+enum KeepaliveType : int32_t {
+    NATT_IPV4 = 0,                          // Keepalive specified by RFC 3948 Sec. 2.3 using IPv4
+    NATT_IPV6 = 1,                          // Keepalive specified by RFC 3948 Sec. 2.3 using IPv6
+};
+
+enum KeepaliveStatusCode : int32_t {
+    ACTIVE,                                 // Keepalive is currently active
+    INACTIVE,                               // Keepalive is inactive, which indicates an error
+    PENDING,                                // Requested keepalive has not yet been processed by
+                                            // the modem. Only allowed in a RESPONSE message to
+                                            // a REQUEST
+};
+
 struct RadioAccessSpecifier {
     RadioAccessNetworks radioAccessNetwork; // The type of network to scan
     vec<GeranBands> geranBands;             // Valid only if radioAccessNetwork = GERAN
@@ -162,3 +175,44 @@
     RadioError error;                       // The error code of the incremental result
     vec<CellInfo> networkInfos;             // List of network information as CellInfo
 };
+
+struct KeepaliveRequest {
+    KeepaliveType type;                     // The format of the keepalive packet
+    vec<uint8_t> sourceAddress;             // source address with type = family, in network
+                                            // byte order
+    int32_t sourcePort;                     // source port if relevant for the given type
+                                            // INT_MAX: 0x7FFFFFFF denotes that the field is unused
+    vec<uint8_t> destinationAddress;        // destination address with type = family, in network
+                                            // byte order
+    int32_t destinationPort;                // destination if relevant for the given type
+                                            // INT_MAX: 0x7FFFFFFF denotes that the field is unused
+    int32_t maxKeepaliveIntervalMillis;     // the max interval between packets, in milliseconds
+    int32_t cid;                            // Context ID, returned in setupDataCallResponse
+                                            // that uniquely identifies the data call to which
+                                            // this keepalive must applied
+};
+
+struct KeepaliveStatus {
+    int32_t sessionHandle;                  // the sessionHandle provided by the api
+    KeepaliveStatusCode code;               // status for the given keepalive
+};
+
+struct ImsiEncryptionInfo {
+    string mcc;                   // MCC of the Carrier.
+    string mnc;                   // MNC of the Carrier.
+    vec<uint8_t> carrierKey;      // Carrier specific key to be used for encryption. It must
+                                  // be opaque to the framework. This is the byte-stream
+                                  // representation of the key. This is an external encoded
+                                  // form for the key used when a standard representation of
+                                  // the key is needed outside the Java Virtual Machine, as
+                                  // when transmitting the key to some other party.
+                                  // The key is encoded according to a standard format
+                                  // (such as X.509 SubjectPublicKeyInfo or PKCS#8), and is
+                                  // returned using the getEncoded method as defined on the
+                                  // java.security.Key interface.
+    string keyIdentifier;         // This is an opaque value we're given by the carrier
+                                  // and is returned to the carrier. This is used by the server to
+                                  // help it locate the private key to decrypt the permanent
+                                  // identity.
+    int64_t expirationTime;       // date-time in UTC when the key will expire.
+};
diff --git a/radio/1.1/vts/functional/Android.bp b/radio/1.1/vts/functional/Android.bp
new file mode 100644
index 0000000..14a2544
--- /dev/null
+++ b/radio/1.1/vts/functional/Android.bp
@@ -0,0 +1,45 @@
+//
+// 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: "VtsHalRadioV1_1TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["radio_hidl_hal_api.cpp",
+           "radio_hidl_hal_test.cpp",
+           "radio_response.cpp",
+           "VtsHalRadioV1_1TargetTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.radio@1.1",
+        "android.hardware.radio@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase",
+                  "RadioHidlHalUtilsBase",
+                  "RadioVtsTestUtilBase"],
+    header_libs: [
+        "radio.util.header@1.0",
+    ],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp b/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp
new file mode 100644
index 0000000..09351c8
--- /dev/null
+++ b/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp
@@ -0,0 +1,27 @@
+/*
+ * 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_v1_1.h>
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(new RadioHidlEnvironment);
+    ::testing::InitGoogleTest(&argc, argv);
+
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+
+    return status;
+}
\ No newline at end of file
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
new file mode 100644
index 0000000..666a317
--- /dev/null
+++ b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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_v1_1.h>
+
+/*
+ * Test IRadio.setSimCardPower() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, setSimCardPower_1_1) {
+    int serial = GetRandomSerialNumber();
+
+    radio_v1_1->setSimCardPower_1_1(serial, CardPowerState::POWER_DOWN);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+    if (cardStatus.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::NONE ||
+                    radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED ||
+                    radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp_v1_1->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE);
+    }
+}
\ No newline at end of file
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_test.cpp b/radio/1.1/vts/functional/radio_hidl_hal_test.cpp
new file mode 100644
index 0000000..164128b
--- /dev/null
+++ b/radio/1.1/vts/functional/radio_hidl_hal_test.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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_v1_1.h>
+
+void RadioHidlTest_v1_1::SetUp() {
+    radio_v1_1 =
+        ::testing::VtsHalHidlTargetTestBase::getService<::android::hardware::radio::V1_1::IRadio>(
+            hidl_string(RADIO_SERVICE_NAME));
+    ASSERT_NE(radio_v1_1, nullptr);
+
+    radioRsp_v1_1 = new RadioResponse_v1_1(*this);
+    ASSERT_NE(radioRsp_v1_1, nullptr);
+
+    count = 0;
+
+    radioInd_v1_1 = NULL;
+    radio_v1_1->setResponseFunctions(radioRsp_v1_1, radioInd_v1_1);
+
+    int serial = GetRandomSerialNumber();
+    radio_v1_1->getIccCardStatus(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_v1_1->rspInfo.error);
+}
\ No newline at end of file
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
new file mode 100644
index 0000000..ae72d8f
--- /dev/null
+++ b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
@@ -0,0 +1,54 @@
+/*
+ * 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 <android/hardware/radio/1.1/IRadio.h>
+#include <android/hardware/radio/1.1/IRadioIndication.h>
+#include <android/hardware/radio/1.1/IRadioResponse.h>
+#include <android/hardware/radio/1.1/types.h>
+
+#include "radio_hidl_hal_utils_v1_0.h"
+
+using namespace ::android::hardware::radio::V1_1;
+
+class RadioHidlTest_v1_1;
+
+/* Callback class for radio response v1_1*/
+class RadioResponse_v1_1 : public RadioResponse {
+   protected:
+    RadioHidlTest_v1_1& parent_v1_1;
+
+   public:
+    RadioResponse_v1_1(RadioHidlTest_v1_1& parent_v1_1);
+    virtual ~RadioResponse_v1_1() = default;
+
+    /* 1.1 Api */
+    Return<void> setCarrierInfoForImsiEncryptionResponse(const RadioResponseInfo& info);
+
+    Return<void> setSimCardPowerResponse_1_1(const RadioResponseInfo& info);
+
+    Return<void> startNetworkScanResponse(const RadioResponseInfo& info);
+
+    Return<void> stopNetworkScanResponse(const RadioResponseInfo& info);
+};
+
+// The main test class for Radio HIDL.
+class RadioHidlTest_v1_1 : public RadioHidlTest {
+   public:
+    virtual void SetUp() override;
+    sp<::android::hardware::radio::V1_1::IRadio> radio_v1_1;
+    sp<RadioResponse_v1_1> radioRsp_v1_1;
+    sp<::android::hardware::radio::V1_1::IRadioIndication> radioInd_v1_1;
+};
\ No newline at end of file
diff --git a/radio/1.1/vts/functional/radio_response.cpp b/radio/1.1/vts/functional/radio_response.cpp
new file mode 100644
index 0000000..c5c8fd7
--- /dev/null
+++ b/radio/1.1/vts/functional/radio_response.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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_v1_1.h>
+
+RadioResponse_v1_1::RadioResponse_v1_1(RadioHidlTest_v1_1& parent)
+    : RadioResponse(parent), parent_v1_1(parent) {}
+
+/* 1.1 Apis */
+Return<void> RadioResponse_v1_1::setCarrierInfoForImsiEncryptionResponse(
+    const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_1::setSimCardPowerResponse_1_1(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_1.notify();
+    return Void();
+}
+
+Return<void> RadioResponse_v1_1::startNetworkScanResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_1::stopNetworkScanResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
\ No newline at end of file
diff --git a/radio/Android.bp b/radio/Android.bp
index dbeca0c..0acb2ee 100644
--- a/radio/Android.bp
+++ b/radio/Android.bp
@@ -3,5 +3,6 @@
     "1.0",
     "1.0/vts/functional",
     "1.1",
+    "1.1/vts/functional",
     "deprecated/1.0",
 ]
diff --git a/sensors/1.0/default/convert.cpp b/sensors/1.0/default/convert.cpp
index 2908737..a5747d4 100644
--- a/sensors/1.0/default/convert.cpp
+++ b/sensors/1.0/default/convert.cpp
@@ -67,9 +67,11 @@
     typedef ::android::hardware::sensors::V1_0::SensorType SensorType;
     typedef ::android::hardware::sensors::V1_0::MetaDataEventType MetaDataEventType;
 
-    dst->sensorHandle = src.sensor;
-    dst->sensorType = (SensorType)src.type;
-    dst->timestamp = src.timestamp;
+    *dst = {
+        .sensorHandle = src.sensor,
+        .sensorType = (SensorType)src.type,
+        .timestamp = src.timestamp
+    };
 
     switch (dst->sensorType) {
         case SensorType::META_DATA:
@@ -206,13 +208,13 @@
 }
 
 void convertToSensorEvent(const Event &src, sensors_event_t *dst) {
-  dst->version = sizeof(sensors_event_t);
-  dst->sensor = src.sensorHandle;
-  dst->type = (int32_t)src.sensorType;
-  dst->reserved0 = 0;
-  dst->timestamp = src.timestamp;
-  dst->flags = 0;
-  dst->reserved1[0] = dst->reserved1[1] = dst->reserved1[2] = 0;
+  *dst = {
+      .version = sizeof(sensors_event_t),
+      .sensor = src.sensorHandle,
+      .type = (int32_t)src.sensorType,
+      .reserved0 = 0,
+      .timestamp = src.timestamp
+  };
 
   switch (src.sensorType) {
       case SensorType::META_DATA:
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index c92603b..3006508 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -543,7 +543,7 @@
 };
 
 const Vec3NormChecker SensorsHidlTest::sAccelNormChecker(
-        Vec3NormChecker::byNominal(GRAVITY_EARTH, 0.5f/*m/s^2*/));
+        Vec3NormChecker::byNominal(GRAVITY_EARTH, 1.0f/*m/s^2*/));
 const Vec3NormChecker SensorsHidlTest::sGyroNormChecker(
         Vec3NormChecker::byNominal(0.f, 0.1f/*rad/s*/));
 
@@ -697,6 +697,7 @@
 SensorFlagBits SensorsHidlTest::expectedReportModeForType(SensorType type) {
   switch (type) {
     case SensorType::ACCELEROMETER:
+    case SensorType::ACCELEROMETER_UNCALIBRATED:
     case SensorType::GYROSCOPE:
     case SensorType::MAGNETIC_FIELD:
     case SensorType::ORIENTATION:
@@ -719,7 +720,6 @@
     case SensorType::AMBIENT_TEMPERATURE:
     case SensorType::HEART_RATE:
     case SensorType::DEVICE_ORIENTATION:
-    case SensorType::MOTION_DETECT:
     case SensorType::STEP_COUNTER:
     case SensorType::LOW_LATENCY_OFFBODY_DETECT:
       return SensorFlagBits::ON_CHANGE_MODE;
@@ -728,6 +728,8 @@
     case SensorType::WAKE_GESTURE:
     case SensorType::GLANCE_GESTURE:
     case SensorType::PICK_UP_GESTURE:
+    case SensorType::MOTION_DETECT:
+    case SensorType::STATIONARY_DETECT:
       return SensorFlagBits::ONE_SHOT_MODE;
 
     case SensorType::STEP_DETECTOR:
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
index b454a06..2d6679f 100644
--- a/wifi/1.0/vts/functional/Android.bp
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -17,10 +17,12 @@
 cc_library_static {
     name: "VtsHalWifiV1_0TargetTestUtil",
     srcs: [
-
         "wifi_hidl_call_util_selftest.cpp",
         "wifi_hidl_test.cpp",
         "wifi_hidl_test_utils.cpp"],
+    export_include_dirs: [
+        "."
+    ],
     shared_libs: [
         "libbase",
         "liblog",
diff --git a/wifi/1.1/Android.bp b/wifi/1.1/Android.bp
new file mode 100644
index 0000000..f991fa5
--- /dev/null
+++ b/wifi/1.1/Android.bp
@@ -0,0 +1,68 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.wifi@1.1_hal",
+    srcs: [
+        "IWifi.hal",
+        "IWifiChip.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.wifi@1.1_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.wifi@1.1",
+    srcs: [
+        ":android.hardware.wifi@1.1_hal",
+    ],
+    out: [
+        "android/hardware/wifi/1.1/WifiAll.cpp",
+        "android/hardware/wifi/1.1/WifiChipAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.wifi@1.1_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.wifi@1.1",
+    srcs: [
+        ":android.hardware.wifi@1.1_hal",
+    ],
+    out: [
+        "android/hardware/wifi/1.1/IWifi.h",
+        "android/hardware/wifi/1.1/IHwWifi.h",
+        "android/hardware/wifi/1.1/BnHwWifi.h",
+        "android/hardware/wifi/1.1/BpHwWifi.h",
+        "android/hardware/wifi/1.1/BsWifi.h",
+        "android/hardware/wifi/1.1/IWifiChip.h",
+        "android/hardware/wifi/1.1/IHwWifiChip.h",
+        "android/hardware/wifi/1.1/BnHwWifiChip.h",
+        "android/hardware/wifi/1.1/BpHwWifiChip.h",
+        "android/hardware/wifi/1.1/BsWifiChip.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.wifi@1.1",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.wifi@1.1_genc++"],
+    generated_headers: ["android.hardware.wifi@1.1_genc++_headers"],
+    export_generated_headers: ["android.hardware.wifi@1.1_genc++_headers"],
+    vendor_available: true,
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.wifi@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.wifi@1.0",
+    ],
+}
diff --git a/wifi/1.1/Android.mk b/wifi/1.1/Android.mk
new file mode 100644
index 0000000..fbc79ca
--- /dev/null
+++ b/wifi/1.1/Android.mk
@@ -0,0 +1,116 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.wifi-V1.1-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.wifi-V1.0-java \
+    android.hidl.base-V1.0-java \
+
+
+#
+# Build IWifi.hal
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_1/IWifi.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IWifi.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.wifi@1.1::IWifi
+
+$(GEN): $(LOCAL_PATH)/IWifi.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IWifiChip.hal
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_1/IWifiChip.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IWifiChip.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.wifi@1.1::IWifiChip
+
+$(GEN): $(LOCAL_PATH)/IWifiChip.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.wifi-V1.1-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.wifi-V1.0-java-static \
+    android.hidl.base-V1.0-java-static \
+
+
+#
+# Build IWifi.hal
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_1/IWifi.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IWifi.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.wifi@1.1::IWifi
+
+$(GEN): $(LOCAL_PATH)/IWifi.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IWifiChip.hal
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_1/IWifiChip.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IWifiChip.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.wifi@1.1::IWifiChip
+
+$(GEN): $(LOCAL_PATH)/IWifiChip.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/wifi/1.1/IWifi.hal b/wifi/1.1/IWifi.hal
new file mode 100644
index 0000000..bd48f57
--- /dev/null
+++ b/wifi/1.1/IWifi.hal
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2016 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.wifi@1.1;
+
+import @1.0::IWifi;
+
+/**
+ * This is the root of the HAL module and is the interface returned when
+ * loading an implementation of the Wi-Fi HAL. There must be at most one
+ * module loaded in the system.
+ * IWifi.getChip() may return either a @1.0::IWifiChip or @1.1::IWifiChip.
+ */
+interface IWifi extends @1.0::IWifi {
+};
diff --git a/wifi/1.1/IWifiChip.hal b/wifi/1.1/IWifiChip.hal
new file mode 100644
index 0000000..7275412
--- /dev/null
+++ b/wifi/1.1/IWifiChip.hal
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2016 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.wifi@1.1;
+
+import @1.0::IWifiChip;
+import @1.0::WifiStatus;
+
+/**
+ * Interface that represents a chip that must be configured as a single unit.
+ * The HAL/driver/firmware will be responsible for determining which phy is used
+ * to perform operations like NAN, RTT, etc.
+ */
+interface IWifiChip extends @1.0::IWifiChip {
+  /**
+   * Capabilities exposed by this chip.
+   */
+  enum ChipCapabilityMask : @1.0::IWifiChip.ChipCapabilityMask {
+    /**
+     * Set/Reset Tx Power limits.
+     */
+    SET_TX_POWER_LIMIT = 1 << 8
+  };
+
+  /**
+   * API to set TX power limit.
+   * This is used for meeting SAR requirements while making VOIP calls for
+   * example.
+   *
+   * @param powerInDbm Power level in dBm.
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.NOT_AVAILABLE|,
+   *         |WifiStatusCode.UNKNOWN|
+   */
+  setTxPowerLimit(int32_t powerInDbm) generates (WifiStatus status);
+
+  /**
+   * API to reset TX power limit.
+   * This is used to set the power back to default values.
+   *
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.NOT_AVAILABLE|,
+   *         |WifiStatusCode.UNKNOWN|
+   */
+  resetTxPowerLimit() generates (WifiStatus status);
+};
diff --git a/wifi/1.0/default/Android.mk b/wifi/1.1/default/Android.mk
similarity index 97%
rename from wifi/1.0/default/Android.mk
rename to wifi/1.1/default/Android.mk
index fe33e08..5758422 100644
--- a/wifi/1.0/default/Android.mk
+++ b/wifi/1.1/default/Android.mk
@@ -38,6 +38,7 @@
     wifi_status_util.cpp
 LOCAL_SHARED_LIBRARIES := \
     android.hardware.wifi@1.0 \
+    android.hardware.wifi@1.1 \
     libbase \
     libcutils \
     libhidlbase \
diff --git a/wifi/1.0/default/THREADING.README b/wifi/1.1/default/THREADING.README
similarity index 100%
rename from wifi/1.0/default/THREADING.README
rename to wifi/1.1/default/THREADING.README
diff --git a/wifi/1.0/default/android.hardware.wifi@1.0-service.rc b/wifi/1.1/default/android.hardware.wifi@1.0-service.rc
similarity index 100%
rename from wifi/1.0/default/android.hardware.wifi@1.0-service.rc
rename to wifi/1.1/default/android.hardware.wifi@1.0-service.rc
diff --git a/wifi/1.0/default/hidl_callback_util.h b/wifi/1.1/default/hidl_callback_util.h
similarity index 98%
rename from wifi/1.0/default/hidl_callback_util.h
rename to wifi/1.1/default/hidl_callback_util.h
index b7100c8..fb13622 100644
--- a/wifi/1.0/default/hidl_callback_util.h
+++ b/wifi/1.1/default/hidl_callback_util.h
@@ -51,7 +51,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_callback_util {
 template <typename CallbackType>
@@ -114,7 +114,7 @@
 
 }  // namespace hidl_callback_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/hidl_return_util.h b/wifi/1.1/default/hidl_return_util.h
similarity index 97%
rename from wifi/1.0/default/hidl_return_util.h
rename to wifi/1.1/default/hidl_return_util.h
index 3f6364b..2f95c23 100644
--- a/wifi/1.0/default/hidl_return_util.h
+++ b/wifi/1.1/default/hidl_return_util.h
@@ -23,9 +23,10 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_return_util {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * These utility functions are used to invoke a method on the provided
@@ -106,7 +107,7 @@
 
 }  // namespace hidl_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/hidl_struct_util.cpp b/wifi/1.1/default/hidl_struct_util.cpp
similarity index 98%
rename from wifi/1.0/default/hidl_struct_util.cpp
rename to wifi/1.1/default/hidl_struct_util.cpp
index fa0279b..a413cbb 100644
--- a/wifi/1.0/default/hidl_struct_util.cpp
+++ b/wifi/1.1/default/hidl_struct_util.cpp
@@ -17,12 +17,15 @@
 #include <android-base/logging.h>
 #include <utils/SystemClock.h>
 
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.1/IWifiChip.h>
+
 #include "hidl_struct_util.h"
 
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_struct_util {
 
@@ -66,6 +69,17 @@
   return {};
 }
 
+V1_1::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability(
+    uint32_t feature) {
+  using HidlChipCaps = V1_1::IWifiChip::ChipCapabilityMask;
+  switch (feature) {
+    case WIFI_FEATURE_SET_TX_POWER_LIMIT:
+      return HidlChipCaps::SET_TX_POWER_LIMIT;
+  };
+  CHECK(false) << "Unknown legacy feature: " << feature;
+  return {};
+}
+
 IWifiStaIface::StaIfaceCapabilityMask
 convertLegacyFeatureToHidlStaIfaceCapability(uint32_t feature) {
   using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
@@ -102,7 +116,9 @@
 }
 
 bool convertLegacyFeaturesToHidlChipCapabilities(
-    uint32_t legacy_logger_feature_set, uint32_t* hidl_caps) {
+    uint32_t legacy_feature_set,
+    uint32_t legacy_logger_feature_set,
+    uint32_t* hidl_caps) {
   if (!hidl_caps) {
     return false;
   }
@@ -117,6 +133,11 @@
       *hidl_caps |= convertLegacyLoggerFeatureToHidlChipCapability(feature);
     }
   }
+  for (const auto feature : {WIFI_FEATURE_SET_TX_POWER_LIMIT}) {
+    if (feature & legacy_feature_set) {
+      *hidl_caps |= convertLegacyFeatureToHidlChipCapability(feature);
+    }
+  }
   // There are no flags for these 3 in the legacy feature set. Adding them to
   // the set because all the current devices support it.
   *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA;
@@ -241,7 +262,6 @@
     return false;
   }
   *hidl_caps = {};
-  *hidl_caps = 0;
   using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
   for (const auto feature : {legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED}) {
     if (feature & legacy_logger_feature_set) {
@@ -2177,7 +2197,7 @@
 }
 }  // namespace hidl_struct_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/hidl_struct_util.h b/wifi/1.1/default/hidl_struct_util.h
similarity index 96%
rename from wifi/1.0/default/hidl_struct_util.h
rename to wifi/1.1/default/hidl_struct_util.h
index c04d92f..7a840f9 100644
--- a/wifi/1.0/default/hidl_struct_util.h
+++ b/wifi/1.1/default/hidl_struct_util.h
@@ -19,7 +19,7 @@
 
 #include <vector>
 
-#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/1.0/types.h>
 
 #include "wifi_legacy_hal.h"
 
@@ -32,13 +32,16 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_struct_util {
+using namespace android::hardware::wifi::V1_0;
 
 // Chip conversion methods.
 bool convertLegacyFeaturesToHidlChipCapabilities(
-    uint32_t legacy_logger_feature_set, uint32_t* hidl_caps);
+    uint32_t legacy_feature_set,
+    uint32_t legacy_logger_feature_set,
+    uint32_t* hidl_caps);
 bool convertLegacyDebugRingBufferStatusToHidl(
     const legacy_hal::wifi_ring_buffer_status& legacy_status,
     WifiDebugRingBufferStatus* hidl_status);
@@ -161,7 +164,7 @@
     std::vector<RttResult>* hidl_results);
 }  // namespace hidl_struct_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/hidl_sync_util.cpp b/wifi/1.1/default/hidl_sync_util.cpp
similarity index 96%
rename from wifi/1.0/default/hidl_sync_util.cpp
rename to wifi/1.1/default/hidl_sync_util.cpp
index 7d47f2f..ba18e34 100644
--- a/wifi/1.0/default/hidl_sync_util.cpp
+++ b/wifi/1.1/default/hidl_sync_util.cpp
@@ -23,7 +23,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_sync_util {
 
@@ -33,7 +33,7 @@
 
 }  // namespace hidl_sync_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/hidl_sync_util.h b/wifi/1.1/default/hidl_sync_util.h
similarity index 96%
rename from wifi/1.0/default/hidl_sync_util.h
rename to wifi/1.1/default/hidl_sync_util.h
index 6631e55..0e882df 100644
--- a/wifi/1.0/default/hidl_sync_util.h
+++ b/wifi/1.1/default/hidl_sync_util.h
@@ -24,13 +24,13 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace hidl_sync_util {
 std::unique_lock<std::recursive_mutex> acquireGlobalLock();
 }  // namespace hidl_sync_util
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/service.cpp b/wifi/1.1/default/service.cpp
similarity index 91%
rename from wifi/1.0/default/service.cpp
rename to wifi/1.1/default/service.cpp
index 059304e..b3fcd50 100644
--- a/wifi/1.0/default/service.cpp
+++ b/wifi/1.1/default/service.cpp
@@ -32,8 +32,8 @@
   configureRpcThreadpool(1, true /* callerWillJoin */);
 
   // Setup hwbinder service
-  android::sp<android::hardware::wifi::V1_0::IWifi> service =
-      new android::hardware::wifi::V1_0::implementation::Wifi();
+  android::sp<android::hardware::wifi::V1_1::IWifi> service =
+      new android::hardware::wifi::V1_1::implementation::Wifi();
   CHECK_EQ(service->registerAsService(), android::NO_ERROR)
       << "Failed to register wifi HAL";
 
diff --git a/wifi/1.0/default/wifi.cpp b/wifi/1.1/default/wifi.cpp
similarity index 99%
rename from wifi/1.0/default/wifi.cpp
rename to wifi/1.1/default/wifi.cpp
index b48844e..4ed1f55 100644
--- a/wifi/1.0/default/wifi.cpp
+++ b/wifi/1.1/default/wifi.cpp
@@ -28,7 +28,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -195,7 +195,7 @@
   return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi.h b/wifi/1.1/default/wifi.h
similarity index 93%
rename from wifi/1.0/default/wifi.h
rename to wifi/1.1/default/wifi.h
index c6fa84c..1ade2d8 100644
--- a/wifi/1.0/default/wifi.h
+++ b/wifi/1.1/default/wifi.h
@@ -20,7 +20,7 @@
 #include <functional>
 
 #include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/1.1/IWifi.h>
 #include <utils/Looper.h>
 
 #include "hidl_callback_util.h"
@@ -31,13 +31,14 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * Root HIDL interface object used to control the Wifi HAL.
  */
-class Wifi : public IWifi {
+class Wifi : public V1_1::IWifi {
  public:
   Wifi();
 
@@ -79,7 +80,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_ap_iface.cpp b/wifi/1.1/default/wifi_ap_iface.cpp
similarity index 98%
rename from wifi/1.0/default/wifi_ap_iface.cpp
rename to wifi/1.1/default/wifi_ap_iface.cpp
index e2beec2..150a6cc 100644
--- a/wifi/1.0/default/wifi_ap_iface.cpp
+++ b/wifi/1.1/default/wifi_ap_iface.cpp
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -100,7 +100,7 @@
   return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
 }
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_ap_iface.h b/wifi/1.1/default/wifi_ap_iface.h
similarity index 94%
rename from wifi/1.0/default/wifi_ap_iface.h
rename to wifi/1.1/default/wifi_ap_iface.h
index efc168a..608fe6b 100644
--- a/wifi/1.0/default/wifi_ap_iface.h
+++ b/wifi/1.1/default/wifi_ap_iface.h
@@ -25,13 +25,14 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a AP Iface instance.
  */
-class WifiApIface : public IWifiApIface {
+class WifiApIface : public V1_0::IWifiApIface {
  public:
   WifiApIface(const std::string& ifname,
               const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -63,7 +64,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_chip.cpp b/wifi/1.1/default/wifi_chip.cpp
similarity index 95%
rename from wifi/1.0/default/wifi_chip.cpp
rename to wifi/1.1/default/wifi_chip.cpp
index 770c83f..2beac26 100644
--- a/wifi/1.0/default/wifi_chip.cpp
+++ b/wifi/1.1/default/wifi_chip.cpp
@@ -46,7 +46,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -343,6 +343,23 @@
                          enable);
 }
 
+Return<void> WifiChip::setTxPowerLimit(
+    int32_t powerInDbm, setTxPowerLimit_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::setTxPowerLimitInternal,
+                         hidl_status_cb,
+                         powerInDbm);
+}
+
+Return<void> WifiChip::resetTxPowerLimit(
+    resetTxPowerLimit_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::resetTxPowerLimitInternal,
+                         hidl_status_cb);
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
   invalidateAndClear(ap_iface_);
   invalidateAndClear(nan_iface_);
@@ -370,7 +387,13 @@
 
 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
   legacy_hal::wifi_error legacy_status;
+  uint32_t legacy_feature_set;
   uint32_t legacy_logger_feature_set;
+  std::tie(legacy_status, legacy_feature_set) =
+      legacy_hal_.lock()->getSupportedFeatureSet();
+  if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+    return {createWifiStatusFromLegacyError(legacy_status), 0};
+  }
   std::tie(legacy_status, legacy_logger_feature_set) =
       legacy_hal_.lock()->getLoggerSupportedFeatureSet();
   if (legacy_status != legacy_hal::WIFI_SUCCESS) {
@@ -378,7 +401,7 @@
   }
   uint32_t hidl_caps;
   if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
-          legacy_logger_feature_set, &hidl_caps)) {
+          legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
     return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
   }
   return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
@@ -801,6 +824,16 @@
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
+WifiStatus WifiChip::setTxPowerLimitInternal(int32_t powerInDbm) {
+  auto legacy_status = legacy_hal_.lock()->setTxPowerLimit(powerInDbm);
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::resetTxPowerLimitInternal() {
+  auto legacy_status = legacy_hal_.lock()->resetTxPowerLimit();
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
 WifiStatus WifiChip::handleChipConfiguration(ChipModeId mode_id) {
   // If the chip is already configured in a different mode, stop
   // the legacy HAL and then start it after firmware mode change.
@@ -869,7 +902,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_chip.h b/wifi/1.1/default/wifi_chip.h
similarity index 95%
rename from wifi/1.0/default/wifi_chip.h
rename to wifi/1.1/default/wifi_chip.h
index 406938c..b7dde50 100644
--- a/wifi/1.0/default/wifi_chip.h
+++ b/wifi/1.1/default/wifi_chip.h
@@ -20,7 +20,7 @@
 #include <map>
 
 #include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.1/IWifiChip.h>
 
 #include "hidl_callback_util.h"
 #include "wifi_ap_iface.h"
@@ -34,15 +34,16 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a Wifi HAL chip instance.
  * Since there is only a single chip instance used today, there is no
  * identifying handle information stored here.
  */
-class WifiChip : public IWifiChip {
+class WifiChip : public V1_1::IWifiChip {
  public:
   WifiChip(
       ChipId chip_id,
@@ -125,6 +126,9 @@
       getDebugHostWakeReasonStats_cb hidl_status_cb) override;
   Return<void> enableDebugErrorAlerts(
       bool enable, enableDebugErrorAlerts_cb hidl_status_cb) override;
+  Return<void> setTxPowerLimit(
+      int32_t powerInDbm, setTxPowerLimit_cb hidl_status_cb) override;
+  Return<void> resetTxPowerLimit(resetTxPowerLimit_cb hidl_status_cb) override;
 
  private:
   void invalidateAndRemoveAllIfaces();
@@ -176,6 +180,8 @@
   std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
   getDebugHostWakeReasonStatsInternal();
   WifiStatus enableDebugErrorAlertsInternal(bool enable);
+  WifiStatus setTxPowerLimitInternal(int32_t powerInDbm);
+  WifiStatus resetTxPowerLimitInternal();
 
   WifiStatus handleChipConfiguration(ChipModeId mode_id);
   WifiStatus registerDebugRingBufferCallback();
@@ -201,7 +207,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_feature_flags.h b/wifi/1.1/default/wifi_feature_flags.h
similarity index 96%
rename from wifi/1.0/default/wifi_feature_flags.h
rename to wifi/1.1/default/wifi_feature_flags.h
index 3502fbd..5939ffb 100644
--- a/wifi/1.0/default/wifi_feature_flags.h
+++ b/wifi/1.1/default/wifi_feature_flags.h
@@ -20,7 +20,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
 class WifiFeatureFlags {
@@ -33,7 +33,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.1/default/wifi_legacy_hal.cpp
similarity index 98%
rename from wifi/1.0/default/wifi_legacy_hal.cpp
rename to wifi/1.1/default/wifi_legacy_hal.cpp
index b6a7550..052aafb 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.1/default/wifi_legacy_hal.cpp
@@ -47,7 +47,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace legacy_hal {
 // Legacy HAL functions accept "C" style function pointers, so use global
@@ -752,6 +752,15 @@
                                                       oui_internal.data());
 }
 
+wifi_error WifiLegacyHal::setTxPowerLimit(int32_t tx_level_dbm) {
+  return global_func_table_.wifi_set_tx_power_limit(wlan_interface_handle_,
+                                                    tx_level_dbm);
+}
+
+wifi_error WifiLegacyHal::resetTxPowerLimit() {
+  return global_func_table_.wifi_reset_tx_power_limit(wlan_interface_handle_);
+}
+
 std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet() {
   uint32_t supported_features;
   wifi_error status = global_func_table_.wifi_get_logger_supported_feature_set(
@@ -1197,11 +1206,19 @@
       id, wlan_interface_handle_, &msg_internal);
 }
 
+typedef struct {
+    u8 num_ndp_instances;
+    NanDataPathId ndp_instance_id;
+} NanDataPathEndSingleNdpIdRequest;
+
 wifi_error WifiLegacyHal::nanDataEnd(transaction_id id,
-                                     const NanDataPathEndRequest& msg) {
-  NanDataPathEndRequest msg_internal(msg);
-  return global_func_table_.wifi_nan_data_end(
-      id, wlan_interface_handle_, &msg_internal);
+                                     uint32_t ndpInstanceId) {
+  NanDataPathEndSingleNdpIdRequest msg;
+  msg.num_ndp_instances = 1;
+  msg.ndp_instance_id = ndpInstanceId;
+  wifi_error status = global_func_table_.wifi_nan_data_end(
+      id, wlan_interface_handle_, (NanDataPathEndRequest*)&msg);
+  return status;
 }
 
 wifi_error WifiLegacyHal::setCountryCode(std::array<int8_t, 2> code) {
@@ -1308,7 +1325,7 @@
 
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_legacy_hal.h b/wifi/1.1/default/wifi_legacy_hal.h
similarity index 98%
rename from wifi/1.0/default/wifi_legacy_hal.h
rename to wifi/1.1/default/wifi_legacy_hal.h
index 1656f68..8d9144d 100644
--- a/wifi/1.0/default/wifi_legacy_hal.h
+++ b/wifi/1.1/default/wifi_legacy_hal.h
@@ -26,7 +26,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 // This is in a separate namespace to prevent typename conflicts between
 // the legacy HAL types and the HIDL interface types.
@@ -205,6 +205,8 @@
       uint32_t period_in_ms);
   wifi_error stopSendingOffloadedPacket(uint32_t cmd_id);
   wifi_error setScanningMacOui(const std::array<uint8_t, 3>& oui);
+  wifi_error setTxPowerLimit(int32_t tx_level_dbm);
+  wifi_error resetTxPowerLimit();
   // Logger/debug functions.
   std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet();
   wifi_error startPktFateMonitoring();
@@ -268,7 +270,7 @@
                                      const NanDataPathInitiatorRequest& msg);
   wifi_error nanDataIndicationResponse(
       transaction_id id, const NanDataPathIndicationResponse& msg);
-  wifi_error nanDataEnd(transaction_id id, const NanDataPathEndRequest& msg);
+  wifi_error nanDataEnd(transaction_id id, uint32_t ndpInstanceId);
   // AP functions.
   wifi_error setCountryCode(std::array<int8_t, 2> code);
 
@@ -298,7 +300,7 @@
 
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_legacy_hal_stubs.cpp b/wifi/1.1/default/wifi_legacy_hal_stubs.cpp
similarity index 97%
rename from wifi/1.0/default/wifi_legacy_hal_stubs.cpp
rename to wifi/1.1/default/wifi_legacy_hal_stubs.cpp
index 2973430..24ed548 100644
--- a/wifi/1.0/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.1/default/wifi_legacy_hal_stubs.cpp
@@ -20,7 +20,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace legacy_hal {
 template <typename>
@@ -132,11 +132,13 @@
   populateStubFor(&hal_fn->wifi_get_roaming_capabilities);
   populateStubFor(&hal_fn->wifi_enable_firmware_roaming);
   populateStubFor(&hal_fn->wifi_configure_roaming);
+  populateStubFor(&hal_fn->wifi_set_tx_power_limit);
+  populateStubFor(&hal_fn->wifi_reset_tx_power_limit);
   return true;
 }
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_legacy_hal_stubs.h b/wifi/1.1/default/wifi_legacy_hal_stubs.h
similarity index 96%
rename from wifi/1.0/default/wifi_legacy_hal_stubs.h
rename to wifi/1.1/default/wifi_legacy_hal_stubs.h
index 1cb5f9d..bfc4c9b 100644
--- a/wifi/1.0/default/wifi_legacy_hal_stubs.h
+++ b/wifi/1.1/default/wifi_legacy_hal_stubs.h
@@ -20,7 +20,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace legacy_hal {
 #include <hardware_legacy/wifi_hal.h>
@@ -28,7 +28,7 @@
 bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn);
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_mode_controller.cpp b/wifi/1.1/default/wifi_mode_controller.cpp
similarity index 98%
rename from wifi/1.0/default/wifi_mode_controller.cpp
rename to wifi/1.1/default/wifi_mode_controller.cpp
index 7e82d4c..b8a44c2 100644
--- a/wifi/1.0/default/wifi_mode_controller.cpp
+++ b/wifi/1.1/default/wifi_mode_controller.cpp
@@ -48,7 +48,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace mode_controller {
 
@@ -80,7 +80,7 @@
 }
 }  // namespace mode_controller
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_mode_controller.h b/wifi/1.1/default/wifi_mode_controller.h
similarity index 95%
rename from wifi/1.0/default/wifi_mode_controller.h
rename to wifi/1.1/default/wifi_mode_controller.h
index a4147a9..6984509 100644
--- a/wifi/1.0/default/wifi_mode_controller.h
+++ b/wifi/1.1/default/wifi_mode_controller.h
@@ -24,9 +24,11 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 namespace mode_controller {
+using namespace android::hardware::wifi::V1_0;
+
 /**
  * Class that encapsulates all firmware mode configuration.
  * This class will perform the necessary firmware reloads to put the chip in the
@@ -51,7 +53,7 @@
 
 }  // namespace mode_controller
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_nan_iface.cpp b/wifi/1.1/default/wifi_nan_iface.cpp
similarity index 98%
rename from wifi/1.0/default/wifi_nan_iface.cpp
rename to wifi/1.1/default/wifi_nan_iface.cpp
index 88fb5b2..a111d06 100644
--- a/wifi/1.0/default/wifi_nan_iface.cpp
+++ b/wifi/1.1/default/wifi_nan_iface.cpp
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -757,19 +757,13 @@
 }
 WifiStatus WifiNanIface::terminateDataPathRequestInternal(
     uint16_t cmd_id, uint32_t ndpInstanceId) {
-  legacy_hal::NanDataPathEndRequest* legacy_msg = (legacy_hal::NanDataPathEndRequest*)malloc(
-      sizeof(legacy_hal::NanDataPathEndRequest) + sizeof(uint32_t));
-  legacy_msg->num_ndp_instances = 1;
-  legacy_msg->ndp_instance_id[0] = ndpInstanceId;
-
   legacy_hal::wifi_error legacy_status =
-      legacy_hal_.lock()->nanDataEnd(cmd_id, *legacy_msg);
-  free(legacy_msg);
+      legacy_hal_.lock()->nanDataEnd(cmd_id, ndpInstanceId);
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_nan_iface.h b/wifi/1.1/default/wifi_nan_iface.h
similarity index 97%
rename from wifi/1.0/default/wifi_nan_iface.h
rename to wifi/1.1/default/wifi_nan_iface.h
index e1edd29..260d8ab 100644
--- a/wifi/1.0/default/wifi_nan_iface.h
+++ b/wifi/1.1/default/wifi_nan_iface.h
@@ -27,13 +27,14 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a NAN Iface instance.
  */
-class WifiNanIface : public IWifiNanIface {
+class WifiNanIface : public V1_0::IWifiNanIface {
  public:
   WifiNanIface(const std::string& ifname,
                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -132,7 +133,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_p2p_iface.cpp b/wifi/1.1/default/wifi_p2p_iface.cpp
similarity index 97%
rename from wifi/1.0/default/wifi_p2p_iface.cpp
rename to wifi/1.1/default/wifi_p2p_iface.cpp
index 0d055f1..78e08db 100644
--- a/wifi/1.0/default/wifi_p2p_iface.cpp
+++ b/wifi/1.1/default/wifi_p2p_iface.cpp
@@ -23,7 +23,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -64,7 +64,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_p2p_iface.h b/wifi/1.1/default/wifi_p2p_iface.h
similarity index 92%
rename from wifi/1.0/default/wifi_p2p_iface.h
rename to wifi/1.1/default/wifi_p2p_iface.h
index d2982db..f563a3d 100644
--- a/wifi/1.0/default/wifi_p2p_iface.h
+++ b/wifi/1.1/default/wifi_p2p_iface.h
@@ -25,13 +25,14 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a P2P Iface instance.
  */
-class WifiP2pIface : public IWifiP2pIface {
+class WifiP2pIface : public V1_0::IWifiP2pIface {
  public:
   WifiP2pIface(const std::string& ifname,
                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -56,7 +57,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_rtt_controller.cpp b/wifi/1.1/default/wifi_rtt_controller.cpp
similarity index 99%
rename from wifi/1.0/default/wifi_rtt_controller.cpp
rename to wifi/1.1/default/wifi_rtt_controller.cpp
index f18feae..9ef702d 100644
--- a/wifi/1.0/default/wifi_rtt_controller.cpp
+++ b/wifi/1.1/default/wifi_rtt_controller.cpp
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -291,7 +291,7 @@
   return createWifiStatusFromLegacyError(legacy_status);
 }
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_rtt_controller.h b/wifi/1.1/default/wifi_rtt_controller.h
similarity index 97%
rename from wifi/1.0/default/wifi_rtt_controller.h
rename to wifi/1.1/default/wifi_rtt_controller.h
index 7c0abca..5437885 100644
--- a/wifi/1.0/default/wifi_rtt_controller.h
+++ b/wifi/1.1/default/wifi_rtt_controller.h
@@ -27,13 +27,13 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
 /**
  * HIDL interface object used to control all RTT operations.
  */
-class WifiRttController : public IWifiRttController {
+class WifiRttController : public V1_0::IWifiRttController {
  public:
   WifiRttController(const sp<IWifiIface>& bound_iface,
                     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -97,7 +97,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_sta_iface.cpp b/wifi/1.1/default/wifi_sta_iface.cpp
similarity index 99%
rename from wifi/1.0/default/wifi_sta_iface.cpp
rename to wifi/1.1/default/wifi_sta_iface.cpp
index 3c52048..28f3f02 100644
--- a/wifi/1.0/default/wifi_sta_iface.cpp
+++ b/wifi/1.1/default/wifi_sta_iface.cpp
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
@@ -623,7 +623,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_sta_iface.h b/wifi/1.1/default/wifi_sta_iface.h
similarity index 97%
rename from wifi/1.0/default/wifi_sta_iface.h
rename to wifi/1.1/default/wifi_sta_iface.h
index 08faa2f..587a5de 100644
--- a/wifi/1.0/default/wifi_sta_iface.h
+++ b/wifi/1.1/default/wifi_sta_iface.h
@@ -27,13 +27,14 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 /**
  * HIDL interface object used to control a STA Iface instance.
  */
-class WifiStaIface : public IWifiStaIface {
+class WifiStaIface : public V1_0::IWifiStaIface {
  public:
   WifiStaIface(const std::string& ifname,
                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
@@ -159,7 +160,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_status_util.cpp b/wifi/1.1/default/wifi_status_util.cpp
similarity index 98%
rename from wifi/1.0/default/wifi_status_util.cpp
rename to wifi/1.1/default/wifi_status_util.cpp
index c2d0758..3a85e09 100644
--- a/wifi/1.0/default/wifi_status_util.cpp
+++ b/wifi/1.1/default/wifi_status_util.cpp
@@ -19,7 +19,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
 
 std::string legacyErrorToString(legacy_hal::wifi_error error) {
@@ -100,7 +100,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.0/default/wifi_status_util.h b/wifi/1.1/default/wifi_status_util.h
similarity index 94%
rename from wifi/1.0/default/wifi_status_util.h
rename to wifi/1.1/default/wifi_status_util.h
index 7f557e0..cc93d66 100644
--- a/wifi/1.0/default/wifi_status_util.h
+++ b/wifi/1.1/default/wifi_status_util.h
@@ -24,8 +24,9 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_0 {
+namespace V1_1 {
 namespace implementation {
+using namespace android::hardware::wifi::V1_0;
 
 std::string legacyErrorToString(legacy_hal::wifi_error error);
 WifiStatus createWifiStatus(WifiStatusCode code,
@@ -36,7 +37,7 @@
 WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error);
 
 }  // namespace implementation
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.1/vts/functional/Android.bp b/wifi/1.1/vts/functional/Android.bp
new file mode 100644
index 0000000..6b0baf7
--- /dev/null
+++ b/wifi/1.1/vts/functional/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2016 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: "VtsHalWifiV1_1TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: [
+        "VtsHalWifiV1_1TargetTest.cpp",
+        "wifi_chip_hidl_test.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.1",
+    ],
+    static_libs: ["VtsHalWifiV1_0TargetTestUtil", "VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp b/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp
new file mode 100644
index 0000000..160fcd2
--- /dev/null
+++ b/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 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 <android-base/logging.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include "wifi_hidl_test_utils.h"
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(new WifiHidlEnvironment);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
diff --git a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
new file mode 100644
index 0000000..839b6c4
--- /dev/null
+++ b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.1/IWifi.h>
+#include <android/hardware/wifi/1.1/IWifiChip.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::ChipId;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_1::IWifi;
+using ::android::hardware::wifi::V1_1::IWifiChip;
+using ::android::hardware::wifi::V1_0::IWifiStaIface;
+
+namespace {
+constexpr int32_t kFakePowerInDbm = -56;
+}; //namespace
+
+/**
+ * Fixture to use for all Wifi chip HIDL interface tests.
+ */
+class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        wifi_chip_ = IWifiChip::castFrom(getWifiChip());
+        ASSERT_NE(nullptr, wifi_chip_.get());
+    }
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+    uint32_t configureChipForStaIfaceAndGetCapabilities() {
+        ChipModeId mode_id;
+        EXPECT_TRUE(configureChipToSupportIfaceType(
+            wifi_chip_, IfaceType::STA, &mode_id));
+        const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
+        EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
+        return status_and_caps.second;
+    }
+
+    sp<IWifiChip> wifi_chip_;
+};
+
+/*
+ * SetTxPowerLimit
+ */
+TEST_F(WifiChipHidlTest, SetTxPowerLimit) {
+    uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
+    const auto& status =
+        HIDL_INVOKE(wifi_chip_, setTxPowerLimit, kFakePowerInDbm);
+    if (caps & IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT) {
+        EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+    } else {
+        EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
+    }
+}
+
+/*
+ * SetTxPowerLimit
+ */
+TEST_F(WifiChipHidlTest, ResetTxPowerLimit) {
+    uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
+    const auto& status =
+        HIDL_INVOKE(wifi_chip_, resetTxPowerLimit);
+    if (caps & IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT) {
+        EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+    } else {
+        EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
+    }
+}
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 523014f..b4ab98f 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -2,6 +2,8 @@
 subdirs = [
     "1.0",
     "1.0/vts/functional",
+    "1.1",
+    "1.1/vts/functional",
     "offload/1.0",
     "offload/1.0/vts/functional",
     "supplicant/1.0",
diff --git a/wifi/offload/1.0/IOffload.hal b/wifi/offload/1.0/IOffload.hal
index 7ad902c..4819519 100644
--- a/wifi/offload/1.0/IOffload.hal
+++ b/wifi/offload/1.0/IOffload.hal
@@ -25,21 +25,28 @@
      *
      * @param ScanParam paramters for scanning
      * @param ScanFilter settings to filter scan result
-     * @return boolean status indicating success (true) when configuration
-     *            is applied or failure (false) for invalid configuration
+     * @return OffloadStatus indicating status of operation provided by this API
+     * If OffloadStatusCode::OK is returned, the operation was successful
+     * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost
+     * If OffloadStatusCode::ERROR is returned, requested operation could not be completed
      */
     @entry
     @callflow(next={"setEventCallback", "subscribeScanResults"})
-    configureScans(ScanParam param, ScanFilter filter);
+    configureScans(ScanParam param, ScanFilter filter) generates (OffloadStatus status);
 
     /**
      * Get scan statistics
      *
+     * @return OffloadStatus indicating status of operation provided by this API
      * @return ScanStats statistics of scans performed
+     * If OffloadStatusCode::OK is returned, the operation was successful
+     * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost
+     * If OffloadStatusCode::ERROR is returned, requested operation could not be completed
+     * If OffloadStatusCode::TIMEOUT is returned, time out waiting for the requested data
      */
     @exit
     @callflow(next={"subscribeScanResults", "unsubscribeScanResults", "getScanStats"})
-    getScanStats() generates (ScanStats scanStats);
+    getScanStats() generates (OffloadStatus status, ScanStats scanStats);
 
     /**
      * Subscribe to asynchronous scan events sent by offload module. This enables
@@ -50,9 +57,13 @@
      *
      * @param delayMs an integer expressing the minimum delay in mS after
      *        subscribing when scan results must be delivered to the client
+     * @return OffloadStatus indicating status of operation provided by this API
+     * If OffloadStatusCode::OK is returned, the operation was successful
+     * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost
+     * If OffloadStatusCode::ERROR is returned, requested operation could not be completed
      */
     @callflow(next={"unsubscribeScanResults", "getScanStats"})
-    subscribeScanResults(uint32_t delayMs);
+    subscribeScanResults(uint32_t delayMs) generates (OffloadStatus status);
 
     /**
      * Unsubscribe to scan events sent by the offload module, hence disabling scans.
diff --git a/wifi/offload/1.0/types.hal b/wifi/offload/1.0/types.hal
index 38d5eda..234f3fc 100644
--- a/wifi/offload/1.0/types.hal
+++ b/wifi/offload/1.0/types.hal
@@ -202,18 +202,25 @@
 /**
  * Defines a list of return codes to indicate status of Offload HAL
  */
-enum OffloadStatus : uint32_t {
+enum OffloadStatusCode : uint32_t {
     /* No error */
-    OFFLOAD_STATUS_OK,
+    OK,
     /* No Connection to underlying implementation */
-    OFFLOAD_STATUS_NO_CONNECTION,
+    NO_CONNECTION,
     /* Operation timeout */
-    OFFLOAD_STATUS_TIMEOUT,
+    TIMEOUT,
     /* Other errors */
-    OFFLOAD_STATUS_ERROR
+    ERROR
 };
 
-
+/**
+ * Generic structures to return the status of an operation
+ */
+struct OffloadStatus {
+  OffloadStatusCode code;
+  /* Error message */
+  string description;
+};
 
 
 
diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
index 3020542..55f5a87 100644
--- a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
+++ b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
@@ -26,6 +26,8 @@
 
 #include <vector>
 
+#include "hidl_call_util.h"
+
 using ::android::hardware::wifi::offload::V1_0::IOffload;
 using ::android::hardware::wifi::offload::V1_0::IOffloadCallback;
 using ::android::hardware::wifi::offload::V1_0::ScanResult;
@@ -33,6 +35,7 @@
 using ::android::hardware::wifi::offload::V1_0::ScanFilter;
 using ::android::hardware::wifi::offload::V1_0::ScanStats;
 using ::android::hardware::wifi::offload::V1_0::OffloadStatus;
+using ::android::hardware::wifi::offload::V1_0::OffloadStatusCode;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::hardware::hidl_vec;
@@ -89,7 +92,7 @@
             return Void();
         };
 
-        Return<void> onError(OffloadStatus status) {
+        Return<void> onError(const OffloadStatus& status) override {
             OffloadCallbackArgs args;
             args.error_code_ = status;
             NotifyFromCallback(kOffloadCallbackSendError, args);
@@ -106,15 +109,15 @@
  */
 TEST_F(WifiOffloadHidlTest, setEventCallback) {
     auto returnObject = wifi_offload_->setEventCallback(wifi_offload_cb_);
-    ASSERT_EQ(returnObject.isOk(), true);
+    ASSERT_EQ(true, returnObject.isOk());
 }
 
 /*
  * Verify that subscribeScanResults method returns without errors
  */
 TEST_F(WifiOffloadHidlTest, subscribeScanResults) {
-    auto returnObject = wifi_offload_->subscribeScanResults(0);
-    ASSERT_EQ(returnObject.isOk(), true);
+    const auto& result = HIDL_INVOKE(wifi_offload_, subscribeScanResults, 0);
+    ASSERT_EQ(OffloadStatusCode::OK, result.code);
 }
 
 /*
@@ -122,7 +125,7 @@
  */
 TEST_F(WifiOffloadHidlTest, unsubscribeScanResults) {
     auto returnObject = wifi_offload_->unsubscribeScanResults();
-    ASSERT_EQ(returnObject.isOk(), true);
+    ASSERT_EQ(true, returnObject.isOk());
 }
 
 /*
@@ -131,21 +134,18 @@
 TEST_F(WifiOffloadHidlTest, configureScans) {
     ScanParam* pScanParam = new ScanParam();
     ScanFilter* pScanFilter = new ScanFilter();
-    auto returnObject =
-        wifi_offload_->configureScans(*pScanParam, *pScanFilter);
-    ASSERT_EQ(returnObject.isOk(), true);
+    const auto& result =
+        HIDL_INVOKE(wifi_offload_, configureScans, *pScanParam, *pScanFilter);
+    ASSERT_EQ(OffloadStatusCode::OK, result.code);
 }
 
 /*
  * Verify that getScanStats returns without any errors
  */
 TEST_F(WifiOffloadHidlTest, getScanStats) {
-    ScanStats* pScanStats = new ScanStats();
-    const auto& returnObject =
-        wifi_offload_->getScanStats([pScanStats](ScanStats scanStats) -> void {
-            *pScanStats = std::move(scanStats);
-        });
-    ASSERT_EQ(returnObject.isOk(), true);
+    const auto& result = HIDL_INVOKE(wifi_offload_, getScanStats);
+    OffloadStatus status = result.first;
+    ASSERT_EQ(OffloadStatusCode::OK, status.code);
 }
 
 /*
@@ -167,7 +167,7 @@
     wifi_offload_cb_->onScanResult(scan_results);
     auto res =
         wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendScanResult);
-    ASSERT_EQ(res.no_timeout, true);
+    ASSERT_EQ(true, res.no_timeout);
 }
 
 /*
@@ -175,9 +175,10 @@
  */
 TEST_F(WifiOffloadHidlTest, getError) {
     wifi_offload_->setEventCallback(wifi_offload_cb_);
-    wifi_offload_cb_->onError(OffloadStatus::OFFLOAD_STATUS_ERROR);
+    OffloadStatus status = {OffloadStatusCode::ERROR, ""};
+    wifi_offload_cb_->onError(status);
     auto res = wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendError);
-    ASSERT_EQ(res.no_timeout, true);
+    ASSERT_EQ(true, res.no_timeout);
 }
 
 // A class for test environment setup
diff --git a/wifi/offload/1.0/vts/functional/hidl_call_util.h b/wifi/offload/1.0/vts/functional/hidl_call_util.h
new file mode 100644
index 0000000..f3ca517
--- /dev/null
+++ b/wifi/offload/1.0/vts/functional/hidl_call_util.h
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <functional>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+namespace {
+namespace detail {
+template <typename>
+struct functionArgSaver;
+
+// Provides a std::function that takes one argument, and a buffer
+// wherein the function will store its argument. The buffer has
+// the same type as the argument, but with const and reference
+// modifiers removed.
+template <typename ArgT>
+struct functionArgSaver<std::function<void(ArgT)>> final {
+    using StorageT = typename std::remove_const<
+        typename std::remove_reference<ArgT>::type>::type;
+
+    std::function<void(ArgT)> saveArgs = [this](ArgT arg) {
+        this->saved_values = arg;
+    };
+
+    StorageT saved_values;
+};
+
+// Provides a std::function that takes two arguments, and a buffer
+// wherein the function will store its arguments. The buffer is a
+// std::pair, whose elements have the same types as the arguments
+// (but with const and reference modifiers removed).
+template <typename Arg1T, typename Arg2T>
+struct functionArgSaver<std::function<void(Arg1T, Arg2T)>> final {
+    using StorageT =
+        std::pair<typename std::remove_const<
+                      typename std::remove_reference<Arg1T>::type>::type,
+                  typename std::remove_const<
+                      typename std::remove_reference<Arg2T>::type>::type>;
+
+    std::function<void(Arg1T, Arg2T)> saveArgs = [this](Arg1T arg1,
+                                                        Arg2T arg2) {
+        this->saved_values = {arg1, arg2};
+    };
+
+    StorageT saved_values;
+};
+
+// Provides a std::function that takes three or more arguments, and a
+// buffer wherein the function will store its arguments. The buffer is a
+// std::tuple whose elements have the same types as the arguments (but
+// with const and reference modifiers removed).
+template <typename... ArgT>
+struct functionArgSaver<std::function<void(ArgT...)>> final {
+    using StorageT = std::tuple<typename std::remove_const<
+        typename std::remove_reference<ArgT>::type>::type...>;
+
+    std::function<void(ArgT...)> saveArgs = [this](ArgT... arg) {
+        this->saved_values = {arg...};
+    };
+
+    StorageT saved_values;
+};
+
+// Invokes |method| on |object|, providing |method| a CallbackT as the
+// final argument. Returns a copy of the parameters that |method| provided
+// to CallbackT. (The parameters are returned by value.)
+template <typename CallbackT, typename MethodT, typename ObjectT,
+          typename... ArgT>
+typename functionArgSaver<CallbackT>::StorageT invokeMethod(
+    MethodT method, ObjectT object, ArgT&&... methodArg) {
+    functionArgSaver<CallbackT> result_buffer;
+    const auto& res = ((*object).*method)(std::forward<ArgT>(methodArg)...,
+                                          result_buffer.saveArgs);
+    EXPECT_TRUE(res.isOk());
+    return result_buffer.saved_values;
+}
+}  // namespace detail
+}  // namespace
+
+// Invokes |method| on |strong_pointer|, passing provided arguments through to
+// |method|.
+//
+// Returns either:
+// - A copy of the result callback parameter (for callbacks with a single
+//   parameter), OR
+// - A pair containing a copy of the result callback parameters (for callbacks
+//   with two parameters), OR
+// - A tuple containing a copy of the result callback paramters (for callbacks
+//   with three or more parameters).
+//
+// Example usage:
+//   EXPECT_EQ(WifiStatusCode::SUCCESS,
+//       HIDL_INVOKE(strong_pointer, methodReturningWifiStatus).code);
+//   EXPECT_EQ(WifiStatusCode::SUCCESS,
+//       HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndOneMore)
+//         .first.code);
+//   EXPECT_EQ(WifiStatusCode::SUCCESS, std::get<0>(
+//       HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndTwoMore))
+//         .code);
+#define HIDL_INVOKE(strong_pointer, method, ...)                              \
+    (detail::invokeMethod<                                                    \
+        std::remove_reference<decltype(*strong_pointer)>::type::method##_cb>( \
+        &std::remove_reference<decltype(*strong_pointer)>::type::method,      \
+        strong_pointer, ##__VA_ARGS__))