Merge "Test for malformed modulus in attestation cert"
diff --git a/biometrics/face/1.0/types.hal b/biometrics/face/1.0/types.hal
index 2628af9..f6827d5 100644
--- a/biometrics/face/1.0/types.hal
+++ b/biometrics/face/1.0/types.hal
@@ -245,9 +245,22 @@
     RECALIBRATE = 13,
 
     /**
+     * The face is too different from a previous acquisition. This condition
+     * only applies to enrollment. This can happen if the user passes the
+     * device to someone else in the middle of enrollment.
+     */
+    TOO_DIFFERENT = 14,
+
+    /**
+     * The face is too similar to a previous acquisition. This condition only
+     * applies to enrollment. The user should change their pose.
+     */
+    TOO_SIMILAR = 15,
+
+    /**
      * Used to enable a vendor-specific acquisition message.
      */
-    VENDOR = 14
+    VENDOR = 16
 };
 
 /**
diff --git a/bluetooth/.clang-format b/bluetooth/.clang-format
new file mode 100644
index 0000000..9564994
--- /dev/null
+++ b/bluetooth/.clang-format
@@ -0,0 +1,20 @@
+#
+# Copyright 2018 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.
+#
+
+BasedOnStyle: Google
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+
diff --git a/bluetooth/1.0/default/async_fd_watcher.cc b/bluetooth/1.0/default/async_fd_watcher.cc
index 7c74643..18098ca 100644
--- a/bluetooth/1.0/default/async_fd_watcher.cc
+++ b/bluetooth/1.0/default/async_fd_watcher.cc
@@ -18,13 +18,13 @@
 
 #include "async_fd_watcher.h"
 
+#include <log/log.h>
 #include <algorithm>
 #include <atomic>
 #include <condition_variable>
 #include <map>
 #include <mutex>
 #include <thread>
-#include <log/log.h>
 #include <vector>
 #include "fcntl.h"
 #include "sys/select.h"
@@ -159,11 +159,9 @@
       TimeoutCallback saved_cb;
       {
         std::unique_lock<std::mutex> guard(timeout_mutex_);
-        if (timeout_ms_ > std::chrono::milliseconds(0))
-          saved_cb = timeout_cb_;
+        if (timeout_ms_ > std::chrono::milliseconds(0)) saved_cb = timeout_cb_;
       }
-      if (saved_cb != nullptr)
-        saved_cb();
+      if (saved_cb != nullptr) saved_cb();
       continue;
     }
 
@@ -180,14 +178,14 @@
       std::unique_lock<std::mutex> guard(internal_mutex_);
       for (auto& it : watched_fds_) {
         if (FD_ISSET(it.first, &read_fds)) {
-        it.second(it.first);
+          it.second(it.first);
         }
       }
     }
   }
 }
 
-} // namespace async
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
+}  // namespace async
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/bluetooth/1.0/default/async_fd_watcher.h b/bluetooth/1.0/default/async_fd_watcher.h
index 358cbc3..b51f921 100644
--- a/bluetooth/1.0/default/async_fd_watcher.h
+++ b/bluetooth/1.0/default/async_fd_watcher.h
@@ -60,8 +60,7 @@
   std::chrono::milliseconds timeout_ms_;
 };
 
-
-} // namespace async
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
+}  // namespace async
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/bluetooth/1.0/default/bluetooth_address.h b/bluetooth/1.0/default/bluetooth_address.h
index 94bf616..010a113 100644
--- a/bluetooth/1.0/default/bluetooth_address.h
+++ b/bluetooth/1.0/default/bluetooth_address.h
@@ -54,8 +54,8 @@
   static bool get_local_address(uint8_t* addr);
 };
 
-} // namespace implementation
-} // namespace V1_0
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/bluetooth/1.0/default/bluetooth_hci.h b/bluetooth/1.0/default/bluetooth_hci.h
index e2797b1..c966990 100644
--- a/bluetooth/1.0/default/bluetooth_hci.h
+++ b/bluetooth/1.0/default/bluetooth_hci.h
@@ -29,8 +29,8 @@
 namespace V1_0 {
 namespace implementation {
 
-using ::android::hardware::Return;
 using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
 
 class BluetoothDeathRecipient;
 
diff --git a/bluetooth/1.0/default/bt_vendor_lib.h b/bluetooth/1.0/default/bt_vendor_lib.h
index c140e52..c4035b7 100644
--- a/bluetooth/1.0/default/bt_vendor_lib.h
+++ b/bluetooth/1.0/default/bt_vendor_lib.h
@@ -418,13 +418,12 @@
 // DIRECTORIES.
 // ONLY USED INSIDE transmit_cb.
 // DO NOT USE IN NEW HAL IMPLEMENTATIONS GOING FORWARD
-typedef struct
-{
-    uint16_t          event;
-    uint16_t          len;
-    uint16_t          offset;
-    uint16_t          layer_specific;
-    uint8_t           data[];
+typedef struct {
+  uint16_t event;
+  uint16_t len;
+  uint16_t offset;
+  uint16_t layer_specific;
+  uint8_t data[];
 } HC_BT_HDR;
 // /MODIFICATION
 
diff --git a/bluetooth/1.0/default/h4_protocol.cc b/bluetooth/1.0/default/h4_protocol.cc
index df40507..98e3273 100644
--- a/bluetooth/1.0/default/h4_protocol.cc
+++ b/bluetooth/1.0/default/h4_protocol.cc
@@ -34,7 +34,8 @@
                         {const_cast<uint8_t*>(data), length}};
   ssize_t ret = 0;
   do {
-    ret = TEMP_FAILURE_RETRY(writev(uart_fd_, iov, sizeof(iov) / sizeof(iov[0])));
+    ret =
+        TEMP_FAILURE_RETRY(writev(uart_fd_, iov, sizeof(iov) / sizeof(iov[0])));
   } while (-1 == ret && EAGAIN == errno);
 
   if (ret == -1) {
diff --git a/bluetooth/1.0/default/hci_packetizer.cc b/bluetooth/1.0/default/hci_packetizer.cc
index 71f4328..7cb3a11 100644
--- a/bluetooth/1.0/default/hci_packetizer.cc
+++ b/bluetooth/1.0/default/hci_packetizer.cc
@@ -46,9 +46,7 @@
 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_) {
diff --git a/bluetooth/1.0/default/hci_protocol.cc b/bluetooth/1.0/default/hci_protocol.cc
index bf94dfe..7e88dc4 100644
--- a/bluetooth/1.0/default/hci_protocol.cc
+++ b/bluetooth/1.0/default/hci_protocol.cc
@@ -20,8 +20,8 @@
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <log/log.h>
+#include <unistd.h>
 
 namespace android {
 namespace hardware {
diff --git a/bluetooth/1.0/default/service.cpp b/bluetooth/1.0/default/service.cpp
index 3a7aad0..dd3f6a9 100644
--- a/bluetooth/1.0/default/service.cpp
+++ b/bluetooth/1.0/default/service.cpp
@@ -24,9 +24,9 @@
 static const size_t kMaxThreads = 5;
 
 // Generated HIDL files
-using android::hardware::bluetooth::V1_0::IBluetoothHci;
 using android::hardware::defaultPassthroughServiceImplementation;
+using android::hardware::bluetooth::V1_0::IBluetoothHci;
 
 int main() {
-    return defaultPassthroughServiceImplementation<IBluetoothHci>(kMaxThreads);
+  return defaultPassthroughServiceImplementation<IBluetoothHci>(kMaxThreads);
 }
diff --git a/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc b/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc
index ee7d8d1..07d8d54 100644
--- a/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc
+++ b/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc
@@ -252,13 +252,13 @@
   });
 
   // Set a timeout flag in each callback.
-  conn_watcher.ConfigureTimeout(
-      std::chrono::milliseconds(500),
-      [&conn_watcher, &timed_out, &timed_out2]() {
-        timed_out = true;
-        conn_watcher.ConfigureTimeout(std::chrono::seconds(1),
+  conn_watcher.ConfigureTimeout(std::chrono::milliseconds(500),
+                                [&conn_watcher, &timed_out, &timed_out2]() {
+                                  timed_out = true;
+                                  conn_watcher.ConfigureTimeout(
+                                      std::chrono::seconds(1),
                                       [&timed_out2]() { timed_out2 = true; });
-      });
+                                });
   EXPECT_FALSE(timed_out);
   EXPECT_FALSE(timed_out2);
   sleep(1);
@@ -385,8 +385,8 @@
   CleanUpServer();
 }
 
-} // namespace implementation
-} // namespace V1_0
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/bluetooth/1.0/default/test/h4_protocol_unittest.cc b/bluetooth/1.0/default/test/h4_protocol_unittest.cc
index ad08086..ba56c0d 100644
--- a/bluetooth/1.0/default/test/h4_protocol_unittest.cc
+++ b/bluetooth/1.0/default/test/h4_protocol_unittest.cc
@@ -36,8 +36,8 @@
 namespace V1_0 {
 namespace implementation {
 
-using ::testing::Eq;
 using hci::H4Protocol;
+using ::testing::Eq;
 
 static char sample_data1[100] = "A point is that which has no part.";
 static char sample_data2[100] = "A line is breadthless length.";
diff --git a/bluetooth/1.0/default/test/mct_protocol_unittest.cc b/bluetooth/1.0/default/test/mct_protocol_unittest.cc
index d45058e..60dbc88 100644
--- a/bluetooth/1.0/default/test/mct_protocol_unittest.cc
+++ b/bluetooth/1.0/default/test/mct_protocol_unittest.cc
@@ -36,8 +36,8 @@
 namespace V1_0 {
 namespace implementation {
 
-using ::testing::Eq;
 using hci::MctProtocol;
+using ::testing::Eq;
 
 static char sample_data1[100] = "A point is that which has no part.";
 static char sample_data2[100] = "A line is breadthless length.";
diff --git a/bluetooth/1.0/default/test/properties.cc b/bluetooth/1.0/default/test/properties.cc
index 6ac4fb4..70de01e 100644
--- a/bluetooth/1.0/default/test/properties.cc
+++ b/bluetooth/1.0/default/test/properties.cc
@@ -36,7 +36,7 @@
 struct property properties[MAX_PROPERTIES];
 
 // Find the correct entry.
-static int property_find(const char *key) {
+static int property_find(const char* key) {
   for (int i = 0; i < num_properties; i++) {
     if (strncmp(properties[i].key, key, PROP_KEY_MAX) == 0) {
       return i;
@@ -45,7 +45,7 @@
   return MAX_PROPERTIES;
 }
 
-int property_set(const char *key, const char *value) {
+int property_set(const char* key, const char* value) {
   if (strnlen(value, PROP_VALUE_MAX) > PROP_VALUE_MAX) return -1;
 
   // Check to see if the property exists.
@@ -63,7 +63,7 @@
   return 0;
 }
 
-int property_get(const char *key, char *value, const char *default_value) {
+int property_get(const char* key, char* value, const char* default_value) {
   // This doesn't mock the behavior of default value
   if (default_value != NULL) ALOGE("%s: default_value is ignored!", __func__);
 
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index a8f5bb4..e5f02f3 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -35,8 +35,8 @@
 
 namespace {
 
-using android::hardware::bluetooth::V1_0::implementation::VendorInterface;
 using android::hardware::hidl_vec;
+using android::hardware::bluetooth::V1_0::implementation::VendorInterface;
 
 struct {
   tINT_CMD_CBACK cb;
@@ -258,8 +258,7 @@
     fd_watcher_.WatchFdForNonBlockingReads(
         fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
     fd_watcher_.WatchFdForNonBlockingReads(
-        fd_list[CH_ACL_IN],
-        [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
+        fd_list[CH_ACL_IN], [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
     hci_ = mct_hci;
   }
 
diff --git a/bluetooth/1.0/default/vendor_interface.h b/bluetooth/1.0/default/vendor_interface.h
index a401ee6..36f4e1b 100644
--- a/bluetooth/1.0/default/vendor_interface.h
+++ b/bluetooth/1.0/default/vendor_interface.h
@@ -40,9 +40,9 @@
                          PacketReadCallback event_cb, PacketReadCallback acl_cb,
                          PacketReadCallback sco_cb);
   static void Shutdown();
-  static VendorInterface *get();
+  static VendorInterface* get();
 
-  size_t Send(uint8_t type, const uint8_t *data, size_t length);
+  size_t Send(uint8_t type, const uint8_t* data, size_t length);
 
   void OnFirmwareConfigured(uint8_t result);
 
@@ -58,15 +58,15 @@
 
   void HandleIncomingEvent(const hidl_vec<uint8_t>& hci_packet);
 
-  void *lib_handle_;
-  bt_vendor_interface_t *lib_interface_;
+  void* lib_handle_;
+  bt_vendor_interface_t* lib_interface_;
   async::AsyncFdWatcher fd_watcher_;
   InitializeCompleteCallback initialize_complete_cb_;
   hci::HciProtocol* hci_;
 
   PacketReadCallback event_cb_;
 
-  FirmwareStartupTimer *firmware_startup_timer_;
+  FirmwareStartupTimer* firmware_startup_timer_;
 };
 
 }  // namespace implementation
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index 439c5fb..88d4234 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -28,13 +28,14 @@
 #include <VtsHalHidlTargetTestEnvBase.h>
 #include <queue>
 
-using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
-using ::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
-using ::android::hardware::bluetooth::V1_0::Status;
+using ::android::sp;
+using ::android::hardware::hidl_death_recipient;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using ::android::sp;
+using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
+using ::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
+using ::android::hardware::bluetooth::V1_0::Status;
 
 #define HCI_MINIMUM_HCI_VERSION 5  // Bluetooth Core Specification 3.0 + HS
 #define HCI_MINIMUM_LMP_VERSION 5  // Bluetooth Core Specification 3.0 + HS
@@ -157,6 +158,11 @@
     ALOGI("%s: getService() for bluetooth is %s", __func__,
           bluetooth->isRemote() ? "remote" : "local");
 
+    bluetooth_hci_death_recipient = new BluetoothHciDeathRecipient();
+    ASSERT_NE(bluetooth_hci_death_recipient, nullptr);
+    ASSERT_TRUE(
+        bluetooth->linkToDeath(bluetooth_hci_death_recipient, 0).isOk());
+
     bluetooth_cb = new BluetoothHciCallbacks(*this);
     ASSERT_NE(bluetooth_cb, nullptr);
 
@@ -191,12 +197,12 @@
   }
 
   virtual void TearDown() override {
-      // Should not be checked in production code
-      ASSERT_TRUE(bluetooth->close().isOk());
-      handle_no_ops();
-      EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
-      EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
-      EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
+    // Should not be checked in production code
+    ASSERT_TRUE(bluetooth->close().isOk());
+    handle_no_ops();
+    EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
+    EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
+    EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
   }
 
   void setBufferSizes();
@@ -214,6 +220,15 @@
   void wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
   int wait_for_completed_packets_event(uint16_t handle);
 
+  class BluetoothHciDeathRecipient : public hidl_death_recipient {
+   public:
+    virtual void serviceDied(
+        uint64_t /*cookie*/,
+        const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+      FAIL();
+    }
+  };
+
   // A simple test implementation of BluetoothHciCallbacks.
   class BluetoothHciCallbacks
       : public ::testing::VtsHalHidlTargetCallbackBase<BluetoothHidlTest>,
@@ -260,6 +275,7 @@
 
   sp<IBluetoothHci> bluetooth;
   sp<BluetoothHciCallbacks> bluetooth_cb;
+  sp<BluetoothHciDeathRecipient> bluetooth_hci_death_recipient;
   std::queue<hidl_vec<uint8_t>> event_queue;
   std::queue<hidl_vec<uint8_t>> acl_queue;
   std::queue<hidl_vec<uint8_t>> sco_queue;
@@ -659,10 +675,11 @@
     EXPECT_LT(0, max_sco_data_packet_length);
     sendAndCheckSCO(1, max_sco_data_packet_length, sco_connection_handles[0]);
     int sco_packets_sent = 1;
-    int completed_packets = wait_for_completed_packets_event(sco_connection_handles[0]);
+    int completed_packets =
+        wait_for_completed_packets_event(sco_connection_handles[0]);
     if (sco_packets_sent != completed_packets) {
-        ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__, sco_packets_sent,
-              completed_packets);
+      ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+            sco_packets_sent, completed_packets);
     }
   }
 
@@ -670,10 +687,11 @@
     EXPECT_LT(0, max_acl_data_packet_length);
     sendAndCheckACL(1, max_acl_data_packet_length, acl_connection_handles[0]);
     int acl_packets_sent = 1;
-    int completed_packets = wait_for_completed_packets_event(acl_connection_handles[0]);
+    int completed_packets =
+        wait_for_completed_packets_event(acl_connection_handles[0]);
     if (acl_packets_sent != completed_packets) {
-        ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__, acl_packets_sent,
-              completed_packets);
+      ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+            acl_packets_sent, completed_packets);
     }
   }
 }
@@ -695,10 +713,11 @@
     sendAndCheckSCO(NUM_SCO_PACKETS_BANDWIDTH, max_sco_data_packet_length,
                     sco_connection_handles[0]);
     int sco_packets_sent = NUM_SCO_PACKETS_BANDWIDTH;
-    int completed_packets = wait_for_completed_packets_event(sco_connection_handles[0]);
+    int completed_packets =
+        wait_for_completed_packets_event(sco_connection_handles[0]);
     if (sco_packets_sent != completed_packets) {
-        ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__, sco_packets_sent,
-              completed_packets);
+      ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+            sco_packets_sent, completed_packets);
     }
   }
 
@@ -707,10 +726,11 @@
     sendAndCheckACL(NUM_ACL_PACKETS_BANDWIDTH, max_acl_data_packet_length,
                     acl_connection_handles[0]);
     int acl_packets_sent = NUM_ACL_PACKETS_BANDWIDTH;
-    int completed_packets = wait_for_completed_packets_event(acl_connection_handles[0]);
+    int completed_packets =
+        wait_for_completed_packets_event(acl_connection_handles[0]);
     if (acl_packets_sent != completed_packets) {
-        ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__, acl_packets_sent,
-              completed_packets);
+      ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+            acl_packets_sent, completed_packets);
     }
   }
 }
diff --git a/bluetooth/a2dp/1.0/default/BluetoothAudioOffload.cpp b/bluetooth/a2dp/1.0/default/BluetoothAudioOffload.cpp
index 2a66abe..9abb88d 100644
--- a/bluetooth/a2dp/1.0/default/BluetoothAudioOffload.cpp
+++ b/bluetooth/a2dp/1.0/default/BluetoothAudioOffload.cpp
@@ -23,47 +23,52 @@
 namespace V1_0 {
 namespace implementation {
 
-IBluetoothAudioOffload* HIDL_FETCH_IBluetoothAudioOffload(const char* /* name */) {
-    return new BluetoothAudioOffload();
+IBluetoothAudioOffload* HIDL_FETCH_IBluetoothAudioOffload(
+    const char* /* name */) {
+  return new BluetoothAudioOffload();
 }
 
-// Methods from ::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload follow.
-Return<::android::hardware::bluetooth::a2dp::V1_0::Status> BluetoothAudioOffload::startSession(
-    const sp<::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost>& hostIf __unused,
-    const ::android::hardware::bluetooth::a2dp::V1_0::CodecConfiguration& codecConfig __unused) {
-    /**
-     * Initialize the audio platform if codecConfiguration is supported.
-     * Save the the IBluetoothAudioHost interface, so that it can be used
-     * later to send stream control commands to the HAL client, based on
-     * interaction with Audio framework.
-     */
-    return ::android::hardware::bluetooth::a2dp::V1_0::Status::FAILURE;
+// Methods from
+// ::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload follow.
+Return<::android::hardware::bluetooth::a2dp::V1_0::Status>
+BluetoothAudioOffload::startSession(
+    const sp<::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost>&
+        hostIf __unused,
+    const ::android::hardware::bluetooth::a2dp::V1_0::CodecConfiguration&
+        codecConfig __unused) {
+  /**
+   * Initialize the audio platform if codecConfiguration is supported.
+   * Save the the IBluetoothAudioHost interface, so that it can be used
+   * later to send stream control commands to the HAL client, based on
+   * interaction with Audio framework.
+   */
+  return ::android::hardware::bluetooth::a2dp::V1_0::Status::FAILURE;
 }
 
 Return<void> BluetoothAudioOffload::streamStarted(
     ::android::hardware::bluetooth::a2dp::V1_0::Status status __unused) {
-    /**
-     * Streaming on control path has started,
-     * HAL server should start the streaming on data path.
-     */
-    return Void();
+  /**
+   * Streaming on control path has started,
+   * HAL server should start the streaming on data path.
+   */
+  return Void();
 }
 
 Return<void> BluetoothAudioOffload::streamSuspended(
     ::android::hardware::bluetooth::a2dp::V1_0::Status status __unused) {
-    /**
-     * Streaming on control path has suspend,
-     * HAL server should suspend the streaming on data path.
-     */
-    return Void();
+  /**
+   * Streaming on control path has suspend,
+   * HAL server should suspend the streaming on data path.
+   */
+  return Void();
 }
 
 Return<void> BluetoothAudioOffload::endSession() {
-    /**
-     * Cleanup the audio platform as remote A2DP Sink device is no
-     * longer active
-     */
-    return Void();
+  /**
+   * Cleanup the audio platform as remote A2DP Sink device is no
+   * longer active
+   */
+  return Void();
 }
 
 }  // namespace implementation
diff --git a/bluetooth/a2dp/1.0/default/BluetoothAudioOffload.h b/bluetooth/a2dp/1.0/default/BluetoothAudioOffload.h
index 5d07b5b..16a83c2 100644
--- a/bluetooth/a2dp/1.0/default/BluetoothAudioOffload.h
+++ b/bluetooth/a2dp/1.0/default/BluetoothAudioOffload.h
@@ -28,27 +28,32 @@
 namespace V1_0 {
 namespace implementation {
 
+using ::android::sp;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_memory;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using ::android::sp;
 
 struct BluetoothAudioOffload : public IBluetoothAudioOffload {
-    BluetoothAudioOffload() {}
-    // Methods from ::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload follow.
-    Return<::android::hardware::bluetooth::a2dp::V1_0::Status> startSession(
-        const sp<::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost>& hostIf,
-        const ::android::hardware::bluetooth::a2dp::V1_0::CodecConfiguration& codecConfig) override;
-    Return<void> streamStarted(::android::hardware::bluetooth::a2dp::V1_0::Status status) override;
-    Return<void> streamSuspended(
-        ::android::hardware::bluetooth::a2dp::V1_0::Status status) override;
-    Return<void> endSession() override;
+  BluetoothAudioOffload() {}
+  // Methods from
+  // ::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload follow.
+  Return<::android::hardware::bluetooth::a2dp::V1_0::Status> startSession(
+      const sp<::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost>&
+          hostIf,
+      const ::android::hardware::bluetooth::a2dp::V1_0::CodecConfiguration&
+          codecConfig) override;
+  Return<void> streamStarted(
+      ::android::hardware::bluetooth::a2dp::V1_0::Status status) override;
+  Return<void> streamSuspended(
+      ::android::hardware::bluetooth::a2dp::V1_0::Status status) override;
+  Return<void> endSession() override;
 };
 
-extern "C" IBluetoothAudioOffload* HIDL_FETCH_IBluetoothAudioOffload(const char* name);
+extern "C" IBluetoothAudioOffload* HIDL_FETCH_IBluetoothAudioOffload(
+    const char* name);
 
 }  // namespace implementation
 }  // namespace V1_0
diff --git a/bluetooth/a2dp/1.0/vts/functional/VtsHalBluetoothA2dpV1_0TargetTest.cpp b/bluetooth/a2dp/1.0/vts/functional/VtsHalBluetoothA2dpV1_0TargetTest.cpp
index 1a0342f..d8d0c29 100644
--- a/bluetooth/a2dp/1.0/vts/functional/VtsHalBluetoothA2dpV1_0TargetTest.cpp
+++ b/bluetooth/a2dp/1.0/vts/functional/VtsHalBluetoothA2dpV1_0TargetTest.cpp
@@ -26,85 +26,92 @@
 #include <VtsHalHidlTargetTestBase.h>
 #include <VtsHalHidlTargetTestEnvBase.h>
 
-using ::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost;
-using ::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload;
-using ::android::hardware::bluetooth::a2dp::V1_0::Status;
-using ::android::hardware::bluetooth::a2dp::V1_0::CodecType;
-using ::android::hardware::bluetooth::a2dp::V1_0::SampleRate;
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
 using ::android::hardware::bluetooth::a2dp::V1_0::BitsPerSample;
 using ::android::hardware::bluetooth::a2dp::V1_0::ChannelMode;
 using ::android::hardware::bluetooth::a2dp::V1_0::CodecConfiguration;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
+using ::android::hardware::bluetooth::a2dp::V1_0::CodecType;
+using ::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost;
+using ::android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload;
+using ::android::hardware::bluetooth::a2dp::V1_0::SampleRate;
+using ::android::hardware::bluetooth::a2dp::V1_0::Status;
 
 // Test environment for Bluetooth HIDL A2DP HAL.
-class BluetoothA2dpHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static BluetoothA2dpHidlEnvironment* Instance() {
-        static BluetoothA2dpHidlEnvironment* instance = new BluetoothA2dpHidlEnvironment;
-        return instance;
-    }
+class BluetoothA2dpHidlEnvironment
+    : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+  // get the test environment singleton
+  static BluetoothA2dpHidlEnvironment* Instance() {
+    static BluetoothA2dpHidlEnvironment* instance =
+        new BluetoothA2dpHidlEnvironment;
+    return instance;
+  }
 
-    virtual void registerTestServices() override { registerTestService<IBluetoothAudioOffload>(); }
+  virtual void registerTestServices() override {
+    registerTestService<IBluetoothAudioOffload>();
+  }
 
-   private:
-    BluetoothA2dpHidlEnvironment() {}
+ private:
+  BluetoothA2dpHidlEnvironment() {}
 };
 
 // The main test class for Bluetooth A2DP HIDL HAL.
 class BluetoothA2dpHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+  virtual void SetUp() override {
+    // currently test passthrough mode only
+    audio_offload =
+        ::testing::VtsHalHidlTargetTestBase::getService<IBluetoothAudioOffload>(
+            BluetoothA2dpHidlEnvironment::Instance()
+                ->getServiceName<IBluetoothAudioOffload>());
+    ASSERT_NE(audio_offload, nullptr);
+
+    audio_host = new BluetoothAudioHost(*this);
+    ASSERT_NE(audio_host, nullptr);
+
+    codec.codecType = CodecType::AAC;
+    codec.sampleRate = SampleRate::RATE_44100;
+    codec.bitsPerSample = BitsPerSample::BITS_16;
+    codec.channelMode = ChannelMode::STEREO;
+    codec.encodedAudioBitrate = 320000;
+    codec.peerMtu = 1000;
+  }
+
+  virtual void TearDown() override {}
+
+  // A simple test implementation of IBluetoothAudioHost.
+  class BluetoothAudioHost
+      : public ::testing::VtsHalHidlTargetCallbackBase<BluetoothA2dpHidlTest>,
+        public IBluetoothAudioHost {
+    BluetoothA2dpHidlTest& parent_;
+
    public:
-    virtual void SetUp() override {
-        // currently test passthrough mode only
-        audio_offload = ::testing::VtsHalHidlTargetTestBase::getService<IBluetoothAudioOffload>(
-            BluetoothA2dpHidlEnvironment::Instance()->getServiceName<IBluetoothAudioOffload>());
-        ASSERT_NE(audio_offload, nullptr);
+    BluetoothAudioHost(BluetoothA2dpHidlTest& parent) : parent_(parent){};
+    virtual ~BluetoothAudioHost() = default;
 
-        audio_host = new BluetoothAudioHost(*this);
-        ASSERT_NE(audio_host, nullptr);
-
-        codec.codecType = CodecType::AAC;
-        codec.sampleRate = SampleRate::RATE_44100;
-        codec.bitsPerSample = BitsPerSample::BITS_16;
-        codec.channelMode = ChannelMode::STEREO;
-        codec.encodedAudioBitrate = 320000;
-        codec.peerMtu = 1000;
-    }
-
-    virtual void TearDown() override {}
-
-    // A simple test implementation of IBluetoothAudioHost.
-    class BluetoothAudioHost
-        : public ::testing::VtsHalHidlTargetCallbackBase<BluetoothA2dpHidlTest>,
-          public IBluetoothAudioHost {
-        BluetoothA2dpHidlTest& parent_;
-
-       public:
-        BluetoothAudioHost(BluetoothA2dpHidlTest& parent) : parent_(parent){};
-        virtual ~BluetoothAudioHost() = default;
-
-        Return<void> startStream() override {
-            parent_.audio_offload->streamStarted(Status::SUCCESS);
-            return Void();
-        };
-
-        Return<void> suspendStream() override {
-            parent_.audio_offload->streamSuspended(Status::SUCCESS);
-            return Void();
-        };
-
-        Return<void> stopStream() override { return Void(); };
+    Return<void> startStream() override {
+      parent_.audio_offload->streamStarted(Status::SUCCESS);
+      return Void();
     };
 
-    // audio_host is for the Audio HAL to send stream start/suspend/stop commands to Bluetooth
-    sp<IBluetoothAudioHost> audio_host;
-    // audio_offload is for the Bluetooth HAL to report session started/ended and handled audio
-    // stream started/suspended
-    sp<IBluetoothAudioOffload> audio_offload;
-    // codec is the currently used codec
-    CodecConfiguration codec;
+    Return<void> suspendStream() override {
+      parent_.audio_offload->streamSuspended(Status::SUCCESS);
+      return Void();
+    };
+
+    Return<void> stopStream() override { return Void(); };
+  };
+
+  // audio_host is for the Audio HAL to send stream start/suspend/stop commands
+  // to Bluetooth
+  sp<IBluetoothAudioHost> audio_host;
+  // audio_offload is for the Bluetooth HAL to report session started/ended and
+  // handled audio stream started/suspended
+  sp<IBluetoothAudioOffload> audio_offload;
+  // codec is the currently used codec
+  CodecConfiguration codec;
 };
 
 // Empty test: Initialize()/Close() are called in SetUp()/TearDown().
@@ -112,15 +119,15 @@
 
 // Test start and end session
 TEST_F(BluetoothA2dpHidlTest, StartAndEndSession) {
-    EXPECT_EQ(Status::SUCCESS, audio_offload->startSession(audio_host, codec));
-    audio_offload->endSession();
+  EXPECT_EQ(Status::SUCCESS, audio_offload->startSession(audio_host, codec));
+  audio_offload->endSession();
 }
 
 int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(BluetoothA2dpHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    BluetoothA2dpHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
+  ::testing::AddGlobalTestEnvironment(BluetoothA2dpHidlEnvironment::Instance());
+  ::testing::InitGoogleTest(&argc, argv);
+  BluetoothA2dpHidlEnvironment::Instance()->init(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
 }
diff --git a/camera/metadata/3.4/types.hal b/camera/metadata/3.4/types.hal
index b228de8..4eb6929 100644
--- a/camera/metadata/3.4/types.hal
+++ b/camera/metadata/3.4/types.hal
@@ -44,6 +44,21 @@
 
     ANDROID_REQUEST_END_3_4,
 
+    /** android.scaler.availableRecommendedStreamConfigurations [static, enum[], ndk_public]
+     *
+     * <p>Recommended stream configurations for common client use cases.</p>
+     */
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS = android.hardware.camera.metadata@3.2::CameraMetadataTag:ANDROID_SCALER_END,
+
+    /** android.scaler.availableRecommendedInputOutputFormatsMap [static, int32, ndk_public]
+     *
+     * <p>Recommended mappings of image formats that are supported by this
+     * camera device for input streams, to their corresponding output formats.</p>
+     */
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP,
+
+    ANDROID_SCALER_END_3_4,
+
     /** android.info.supportedBufferManagementVersion [static, enum, system]
      *
      * <p>The version of buffer management API this camera device supports and opts into.</p>
@@ -52,12 +67,52 @@
 
     ANDROID_INFO_END_3_4,
 
+    /** android.depth.availableRecommendedDepthStreamConfigurations [static, int32[], ndk_public]
+     *
+     * <p>Recommended depth stream configurations for common client use cases.</p>
+     */
+    ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS = android.hardware.camera.metadata@3.2::CameraMetadataTag:ANDROID_DEPTH_END,
+
+    ANDROID_DEPTH_END_3_4,
+
 };
 
 /*
  * Enumeration definitions for the various entries that need them
  */
 
+/** android.scaler.availableFormats enumeration values added since v3.2
+ * @see ANDROID_SCALER_AVAILABLE_FORMATS
+ */
+enum CameraMetadataEnumAndroidScalerAvailableFormats :
+        @3.2::CameraMetadataEnumAndroidScalerAvailableFormats {
+    ANDROID_SCALER_AVAILABLE_FORMATS_RAW10                      = 0x25,
+    ANDROID_SCALER_AVAILABLE_FORMATS_RAW12                      = 0x26,
+    ANDROID_SCALER_AVAILABLE_FORMATS_Y8                         = 0x20203859,
+};
+
+/** android.scaler.availableRecommendedStreamConfigurations enumeration values
+ * @see ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS
+ */
+enum CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations : uint32_t {
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW
+                                                                 = 0x0,
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD
+                                                                 = 0x1,
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT
+                                                                 = 0x2,
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT
+                                                                 = 0x3,
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL
+                                                                 = 0x4,
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW
+                                                                 = 0x5,
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END
+                                                                 = 0x6,
+    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START
+                                                                 = 0x18,
+};
+
 /** android.info.supportedBufferManagementVersion enumeration values
  * @see ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION
  */
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 94d06e8..837905c 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -681,6 +681,7 @@
             const CameraMetadata& chars, int deviceVersion,
             const hidl_vec<hidl_string>& deviceNames);
     void verifyCameraCharacteristics(Status status, const CameraMetadata& chars);
+    void verifyRecommendedConfigs(const CameraMetadata& metadata);
 
     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
             std::vector<AvailableStream> &outputStreams,
@@ -698,7 +699,7 @@
             /*out*/);
     static Status pickConstrainedModeSize(camera_metadata_t *staticMeta,
             AvailableStream &hfrStream);
-    static Status isZSLModeAvailable(camera_metadata_t *staticMeta);
+    static Status isZSLModeAvailable(const camera_metadata_t *staticMeta);
     static Status getZSLInputOutputMap(camera_metadata_t *staticMeta,
             std::vector<AvailableZSLInputOutput> &inputOutputMap);
     static Status findLargestSize(
@@ -2079,7 +2080,7 @@
 
                 ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) {
                     verifyCameraCharacteristics(status, chars);
-
+                    verifyRecommendedConfigs(chars);
                     verifyLogicalCameraMetadata(name, device3_x, chars, deviceVersion,
                             cameraDeviceNames);
                 });
@@ -4323,7 +4324,7 @@
 
 // Check whether ZSL is available using the static camera
 // characteristics.
-Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) {
+Status CameraHidlTest::isZSLModeAvailable(const camera_metadata_t *staticMeta) {
     Status ret = Status::METHOD_NOT_SUPPORTED;
     if (nullptr == staticMeta) {
         return Status::ILLEGAL_ARGUMENT;
@@ -4978,6 +4979,94 @@
     ASSERT_TRUE(ret.isOk());
 }
 
+void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) {
+    size_t CONFIG_ENTRY_SIZE = 5;
+    size_t CONFIG_ENTRY_TYPE_OFFSET = 3;
+    size_t CONFIG_ENTRY_BITFIELD_OFFSET = 4;
+    uint32_t maxPublicUsecase =
+            ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END;
+    uint32_t vendorUsecaseStart =
+            ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START;
+    uint32_t usecaseMask = (1 << vendorUsecaseStart) - 1;
+    usecaseMask &= ~((1 << maxPublicUsecase) - 1);
+
+    const camera_metadata_t* metadata = reinterpret_cast<const camera_metadata_t*> (chars.data());
+
+    camera_metadata_ro_entry recommendedConfigsEntry, recommendedDepthConfigsEntry, ioMapEntry;
+    recommendedConfigsEntry.count = recommendedDepthConfigsEntry.count = ioMapEntry.count = 0;
+    int retCode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS, &recommendedConfigsEntry);
+    int depthRetCode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS,
+            &recommendedDepthConfigsEntry);
+    int ioRetCode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP, &ioMapEntry);
+    if ((0 != retCode) && (0 != depthRetCode)) {
+        //In case both regular and depth recommended configurations are absent,
+        //I/O should be absent as well.
+        ASSERT_NE(ioRetCode, 0);
+        return;
+    }
+
+    camera_metadata_ro_entry availableKeysEntry;
+    retCode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &availableKeysEntry);
+    ASSERT_TRUE((0 == retCode) && (availableKeysEntry.count > 0));
+    std::vector<int32_t> availableKeys;
+    availableKeys.reserve(availableKeysEntry.count);
+    availableKeys.insert(availableKeys.end(), availableKeysEntry.data.i32,
+            availableKeysEntry.data.i32 + availableKeysEntry.count);
+
+    if (recommendedConfigsEntry.count > 0) {
+        ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
+                    ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS),
+                availableKeys.end());
+        ASSERT_EQ((recommendedConfigsEntry.count % CONFIG_ENTRY_SIZE), 0);
+        for (size_t i = 0; i < recommendedConfigsEntry.count; i += CONFIG_ENTRY_SIZE) {
+            int32_t entryType =
+                recommendedConfigsEntry.data.i32[i + CONFIG_ENTRY_TYPE_OFFSET];
+            uint32_t bitfield =
+                recommendedConfigsEntry.data.i32[i + CONFIG_ENTRY_BITFIELD_OFFSET];
+            ASSERT_TRUE((entryType ==
+                     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) ||
+                    (entryType ==
+                     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT));
+            ASSERT_TRUE((bitfield & usecaseMask) == 0);
+        }
+    }
+
+    if (recommendedDepthConfigsEntry.count > 0) {
+        ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
+                    ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS),
+                availableKeys.end());
+        ASSERT_EQ((recommendedDepthConfigsEntry.count % CONFIG_ENTRY_SIZE), 0);
+        for (size_t i = 0; i < recommendedDepthConfigsEntry.count; i += CONFIG_ENTRY_SIZE) {
+            int32_t entryType =
+                recommendedDepthConfigsEntry.data.i32[i + CONFIG_ENTRY_TYPE_OFFSET];
+            uint32_t bitfield =
+                recommendedDepthConfigsEntry.data.i32[i + CONFIG_ENTRY_BITFIELD_OFFSET];
+            ASSERT_TRUE((entryType ==
+                     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) ||
+                    (entryType ==
+                     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT));
+            ASSERT_TRUE((bitfield & usecaseMask) == 0);
+        }
+
+        if (recommendedConfigsEntry.count == 0) {
+            //In case regular recommended configurations are absent but suggested depth
+            //configurations are present, I/O should be absent.
+            ASSERT_NE(ioRetCode, 0);
+        }
+    }
+
+    if ((ioRetCode == 0) && (ioMapEntry.count > 0)) {
+        ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
+                    ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP),
+                availableKeys.end());
+        ASSERT_EQ(isZSLModeAvailable(metadata), Status::OK);
+    }
+}
+
 int main(int argc, char **argv) {
   ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/compatibility_matrices/compatibility_matrix.3.xml b/compatibility_matrices/compatibility_matrix.3.xml
index e13d293..4cb3776 100644
--- a/compatibility_matrices/compatibility_matrix.3.xml
+++ b/compatibility_matrices/compatibility_matrix.3.xml
@@ -193,7 +193,7 @@
     </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.graphics.composer</name>
-        <version>2.1-2</version>
+        <version>2.1-3</version>
         <interface>
             <name>IComposer</name>
             <instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index bc453d8..e117a98 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -286,7 +286,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.neuralnetworks</name>
-        <version>1.0</version>
+        <version>1.0-2</version>
         <interface>
             <name>IDevice</name>
             <regex-instance>.*</regex-instance>
diff --git a/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp b/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
index a1676be..70b5830 100644
--- a/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
+++ b/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
@@ -131,6 +131,27 @@
     }
 }
 
+/**
+ * Make sure the constrains of hasWideColorDisplay, hasHDRDisplay
+ * are enforced.
+ */
+TEST_F(ConfigstoreHidlTest, TestColorConstrainsBasic) {
+    bool hasWideColorDisplay;
+    bool hasHDRDisplay;
+
+    Return<void> status = sfConfigs->hasWideColorDisplay(
+        [&](OptionalBool arg) { hasWideColorDisplay = arg.specified; });
+    EXPECT_OK(status);
+
+    status = sfConfigs->hasHDRDisplay([&](OptionalBool arg) { hasHDRDisplay = arg.specified; });
+    EXPECT_OK(status);
+
+    // When hasHDRDisplay returns true, hasWideColorDisplay must also return true.
+    if (hasHDRDisplay) {
+        ASSERT_TRUE(hasWideColorDisplay);
+    }
+}
+
 int main(int argc, char** argv) {
     ::testing::AddGlobalTestEnvironment(ConfigstoreHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
diff --git a/configstore/1.2/Android.bp b/configstore/1.2/Android.bp
index c525a72..bb4dd4a 100644
--- a/configstore/1.2/Android.bp
+++ b/configstore/1.2/Android.bp
@@ -10,10 +10,13 @@
         "ISurfaceFlingerConfigs.hal",
     ],
     interfaces: [
-        "android.hardware.configstore@1.1",
         "android.hardware.configstore@1.0",
+        "android.hardware.configstore@1.1",
+        "android.hardware.graphics.common@1.0",
+        "android.hardware.graphics.common@1.1",
         "android.hardware.graphics.common@1.2",
         "android.hidl.base@1.0",
     ],
     gen_java: true,
 }
+
diff --git a/configstore/1.2/ISurfaceFlingerConfigs.hal b/configstore/1.2/ISurfaceFlingerConfigs.hal
index 9553fca..e91b2c7 100644
--- a/configstore/1.2/ISurfaceFlingerConfigs.hal
+++ b/configstore/1.2/ISurfaceFlingerConfigs.hal
@@ -34,25 +34,39 @@
     useColorManagement() generates (OptionalBool value);
 
     /**
-     * Returns the default data space and default pixel format that
-     * SurfaceFlinger expects to receive and output.
-     * To determine the default data space and default pixel format,
-     * there are a few things we recommend to consider:
+     * Returns the default data space and pixel format that SurfaceFlinger
+     * expects to receive and output as well as the wide color gamut data space
+     * and pixel format for wide color gamut surfaces.
+     * To determine the data space and pixel format, there are a few things
+     * we recommend to consider:
      *
-     *   1. Hardware composer's capability to composite contents with the
+     *   1. Hardware composer's capability to composite contents with the chosen
      *      data space and pixel format efficiently;
      *   2. Hardware composer's ability to composite contents when sRGB contents
-     *      and the chosen data space contents coexist;
+     *      and the chosen wide color gamut data space contents coexist;
      *   3. For better blending, consider using pixel format where the alpha
      *      channel has as many bits as the RGB color channel.
+     *   4. Memory consumption and efficient buffer compression when considering
+     *      more bits in pixel format.
      *
-     * @return dataSpace is the default data space that SurfaceFlinger expects.
+     * @return dataspace is the default data space that SurfaceFlinger expects.
      *         The data space must not be Dataspace::UNKNOWN, if unspecified,
      *         the default data space is Dataspace::V0_SRGB;
      * @return pixelFormat is the default pixel format that SurfaceFlinger
      *         expects. If unspecified, the default pixel format is
      *         PixelFormat::RGBA_8888.
+     * @return wcgDataspace is the data space that SurfaceFlinger expects for
+     *         wide color gamut surfaces.
+     *         When hasWideColorDisplay returns true, this API must return a
+     *         valid wide color gamut data space.
+     *         The data space must not be UNKNOWN, if unspecified, the data space
+     *         is V0_SRGB by default, which essentially indicates there's no wide
+     *         color gamut, meaning hasWideColorDisplay returns false.
+     * @return wcgPixelFormat is the pixel format that SurfaceFlinger expects for
+     *         wide color gamut surfaces. If unspecified, the pixel format is
+     *         PixelFormat::RGBA_8888 by default.
      */
     getCompositionPreference()
-        generates (Dataspace dataSpace, PixelFormat pixelFormat);
+        generates (Dataspace dataspace, PixelFormat pixelFormat,
+                   Dataspace wcgDataspace, PixelFormat wcgPixelFormat);
 };
diff --git a/configstore/1.2/default/SurfaceFlingerConfigs.cpp b/configstore/1.2/default/SurfaceFlingerConfigs.cpp
index b78d15e..c2cf374 100644
--- a/configstore/1.2/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.2/default/SurfaceFlingerConfigs.cpp
@@ -203,22 +203,41 @@
     return Void();
 }
 
-#ifdef COMPOSITION_DATA_SPACE
-static_assert(COMPOSITION_DATA_SPACE != 0, "Expected composition data space must not be UNKNOWN");
+#ifdef DEFAULT_COMPOSITION_DATA_SPACE
+static_assert(DEFAULT_COMPOSITION_DATA_SPACE != 0,
+              "Default composition data space must not be UNKNOWN");
+#endif
+
+#ifdef WCG_COMPOSITION_DATA_SPACE
+static_assert(WCG_COMPOSITION_DATA_SPACE != 0,
+              "Wide color gamut composition data space must not be UNKNOWN");
 #endif
 
 Return<void> SurfaceFlingerConfigs::getCompositionPreference(getCompositionPreference_cb _hidl_cb) {
-    Dataspace dataSpace = Dataspace::V0_SRGB;
-    PixelFormat pixelFormat = PixelFormat::RGBA_8888;
+    Dataspace defaultDataspace = Dataspace::V0_SRGB;
+    PixelFormat defaultPixelFormat = PixelFormat::RGBA_8888;
 
-#ifdef COMPOSITION_DATA_SPACE
-    dataSpace = static_cast<Dataspace>(COMPOSITION_DATA_SPACE);
+#ifdef DEFAULT_COMPOSITION_DATA_SPACE
+    defaultDataspace = static_cast<Dataspace>(DEFAULT_COMPOSITION_DATA_SPACE);
 #endif
 
-#ifdef COMPOSITION_PIXEL_FORMAT
-    pixelFormat = static_cast<PixelFormat>(COMPOSITION_PIXEL_FORMAT);
+#ifdef DEFAULT_COMPOSITION_PIXEL_FORMAT
+    defaultPixelFormat = static_cast<PixelFormat>(DEFAULT_COMPOSITION_PIXEL_FORMAT);
 #endif
-    _hidl_cb(dataSpace, pixelFormat);
+
+    Dataspace wideColorGamutDataspace = Dataspace::V0_SRGB;
+    PixelFormat wideColorGamutPixelFormat = PixelFormat::RGBA_8888;
+
+#ifdef WCG_COMPOSITION_DATA_SPACE
+    wideColorGamutDataspace = static_cast<Dataspace>(WCG_COMPOSITION_DATA_SPACE);
+#endif
+
+#ifdef WCG_COMPOSITION_PIXEL_FORMAT
+    wideColorGamutPixelFormat = static_cast<PixelFormat>(WCG_COMPOSITION_PIXEL_FORMAT);
+#endif
+
+    _hidl_cb(defaultDataspace, defaultPixelFormat, wideColorGamutDataspace,
+             wideColorGamutPixelFormat);
     return Void();
 }
 
diff --git a/configstore/1.2/default/surfaceflinger.mk b/configstore/1.2/default/surfaceflinger.mk
index f323999..dab6aa5 100644
--- a/configstore/1.2/default/surfaceflinger.mk
+++ b/configstore/1.2/default/surfaceflinger.mk
@@ -59,10 +59,18 @@
     LOCAL_CFLAGS += -DUSE_COLOR_MANAGEMENT
 endif
 
-ifneq ($(SF_COMPOSITION_DATA_SPACE),)
-    LOCAL_CFLAGS += -DCOMPOSITION_DATA_SPACE=$(SF_COMPOSITION_DATA_SPACE)
+ifneq ($(SF_DEFAULT_COMPOSITION_DATA_SPACE),)
+    LOCAL_CFLAGS += -DDEFAULT_COMPOSITION_DATA_SPACE=$(SF_DEFAULT_COMPOSITION_DATA_SPACE)
 endif
 
-ifneq ($(SF_COMPOSITION_PIXEL_FORMAT),)
-    LOCAL_CFLAGS += -DCOMPOSITION_PIXEL_FORMAT=$(SF_COMPOSITION_PIXEL_FORMAT)
+ifneq ($(SF_DEFAULT_COMPOSITION_PIXEL_FORMAT),)
+    LOCAL_CFLAGS += -DDEFAULT_COMPOSITION_PIXEL_FORMAT=$(SF_DEFAULT_COMPOSITION_PIXEL_FORMAT)
+endif
+
+ifneq ($(SF_WCG_COMPOSITION_DATA_SPACE),)
+    LOCAL_CFLAGS += -DWCG_COMPOSITION_DATA_SPACE=$(SF_WCG_COMPOSITION_DATA_SPACE)
+endif
+
+ifneq ($(SF_WCG_COMPOSITION_PIXEL_FORMAT),)
+    LOCAL_CFLAGS += -DWCG_COMPOSITION_PIXEL_FORMAT=$(SF_WCG_COMPOSITION_PIXEL_FORMAT)
 endif
diff --git a/configstore/1.2/vts/functional/Android.bp b/configstore/1.2/vts/functional/Android.bp
new file mode 100644
index 0000000..5f1eca6
--- /dev/null
+++ b/configstore/1.2/vts/functional/Android.bp
@@ -0,0 +1,27 @@
+//
+// Copyright (C) 2018 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: "VtsHalConfigstoreV1_2TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: ["VtsHalConfigstoreV1_2TargetTest.cpp"],
+    static_libs: [
+        "android.hardware.configstore@1.0",
+        "android.hardware.configstore@1.1",
+        "android.hardware.configstore@1.2",
+    ],
+}
+
diff --git a/configstore/1.2/vts/functional/OWNERS b/configstore/1.2/vts/functional/OWNERS
new file mode 100644
index 0000000..2b4fb8c
--- /dev/null
+++ b/configstore/1.2/vts/functional/OWNERS
@@ -0,0 +1,7 @@
+# Graphics team
+lpy@google.com
+olv@google.com
+stoza@google.com
+
+# VTS team
+yim@google.com
diff --git a/configstore/1.2/vts/functional/VtsHalConfigstoreV1_2TargetTest.cpp b/configstore/1.2/vts/functional/VtsHalConfigstoreV1_2TargetTest.cpp
new file mode 100644
index 0000000..dc5fec5
--- /dev/null
+++ b/configstore/1.2/vts/functional/VtsHalConfigstoreV1_2TargetTest.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ConfigstoreHidlHalTest"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/configstore/1.0/types.h>
+#include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h>
+#include <unistd.h>
+
+using ::android::sp;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::configstore::V1_0::OptionalBool;
+using ::android::hardware::configstore::V1_0::OptionalInt64;
+using ::android::hardware::configstore::V1_0::OptionalUInt64;
+using ::android::hardware::configstore::V1_2::ISurfaceFlingerConfigs;
+using ::android::hardware::graphics::common::V1_1::PixelFormat;
+using ::android::hardware::graphics::common::V1_2::Dataspace;
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
+
+// Test environment for Configstore HIDL HAL.
+class ConfigstoreHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static ConfigstoreHidlEnvironment* Instance() {
+        static ConfigstoreHidlEnvironment* instance = new ConfigstoreHidlEnvironment;
+        return instance;
+    }
+
+    virtual void registerTestServices() override { registerTestService<ISurfaceFlingerConfigs>(); }
+};
+
+class ConfigstoreHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    sp<ISurfaceFlingerConfigs> sfConfigs;
+
+    virtual void SetUp() override {
+        sfConfigs = ::testing::VtsHalHidlTargetTestBase::getService<ISurfaceFlingerConfigs>(
+            ConfigstoreHidlEnvironment::Instance()->getServiceName<ISurfaceFlingerConfigs>());
+        ASSERT_NE(sfConfigs, nullptr);
+    }
+
+    virtual void TearDown() override {}
+
+    bool isSupportedWideColorGamut(Dataspace dataspace) {
+        Dataspace standard = static_cast<Dataspace>(dataspace & Dataspace::STANDARD_MASK);
+        return standard == Dataspace::STANDARD_DCI_P3 || standard == Dataspace::STANDARD_BT2020;
+    }
+};
+
+/**
+ * Make sure the constrains of hasWideColorDisplay, hasHDRDisplay
+ * and useColorManagement are enforced.
+ */
+TEST_F(ConfigstoreHidlTest, TestColorConstrainsWithColorManagement) {
+    bool hasWideColorDisplay;
+    bool hasHDRDisplay;
+    bool useColorManagement;
+
+    Return<void> status = sfConfigs->hasWideColorDisplay(
+        [&](OptionalBool arg) { hasWideColorDisplay = arg.specified; });
+    EXPECT_OK(status);
+
+    status = sfConfigs->hasHDRDisplay([&](OptionalBool arg) { hasHDRDisplay = arg.specified; });
+    EXPECT_OK(status);
+
+    status = sfConfigs->useColorManagement(
+        [&](OptionalBool arg) { useColorManagement = arg.specified; });
+    EXPECT_OK(status);
+
+    // When hasHDRDisplay returns true, hasWideColorDisplay must also return true.
+    if (hasHDRDisplay) {
+        ASSERT_TRUE(hasWideColorDisplay);
+    }
+
+    // When hasWideColorDisplay returns true, useColorManagement
+    // must also return true.
+    if (hasWideColorDisplay) {
+        ASSERT_TRUE(useColorManagement);
+    }
+}
+
+TEST_F(ConfigstoreHidlTest, TestGetCompositionPreference) {
+    bool hasWideColorDisplay;
+
+    Return<void> status = sfConfigs->hasWideColorDisplay(
+        [&](OptionalBool arg) { hasWideColorDisplay = arg.specified; });
+    EXPECT_OK(status);
+
+    Dataspace defaultDataspace, wcgDataspace;
+
+    status = sfConfigs->getCompositionPreference(
+        [&](auto tmpDefaultDataspace, PixelFormat, auto tmpWcgDataspace, PixelFormat) {
+            defaultDataspace = tmpDefaultDataspace;
+            wcgDataspace = tmpWcgDataspace;
+        });
+    EXPECT_OK(status);
+
+    // Default data space and wide color gamut data space must not be UNKNOWN.
+    ASSERT_TRUE(defaultDataspace != Dataspace::UNKNOWN && wcgDataspace != Dataspace::UNKNOWN);
+
+    // If hasWideColorDisplay returns true, the wide color gamut data space must be a valid wide
+    // color gamut.
+    if (hasWideColorDisplay) {
+        ASSERT_TRUE(isSupportedWideColorGamut(wcgDataspace));
+    }
+}
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(ConfigstoreHidlEnvironment::Instance());
+    ::testing::InitGoogleTest(&argc, argv);
+    ConfigstoreHidlEnvironment::Instance()->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
diff --git a/current.txt b/current.txt
index a7989d4..8b10648 100644
--- a/current.txt
+++ b/current.txt
@@ -390,7 +390,7 @@
 684702a60deef03a1e8093961dc0a18c555c857ad5a77ba7340b0635ae01eb70 android.hardware.camera.device@3.4::ICameraDeviceSession
 dd2436f251a90f3e5e7ed773b1aeae21e381b00ae26b10ebe3a1001c894e5980 android.hardware.camera.metadata@3.3::types
 da33234403ff5d60f3473711917b9948e6484a4260b5247acdafb111193a9de2 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
-78886339f2c848cf13c1edd3ebba63f89796b2620d3bf3b5c21d038a53519ba0 android.hardware.gnss@1.0::IGnssMeasurementCallback
+d702fb01dc2a0733aa820b7eb65435ee3334f75632ef880bafd2fb8803a20a58 android.hardware.gnss@1.0::IGnssMeasurementCallback
 b7ecf29927055ec422ec44bf776223f07d79ad9f92ccf9becf167e62c2607e7a android.hardware.keymaster@4.0::IKeymasterDevice
 574e8f1499436fb4075894dcae0b36682427956ecb114f17f1fe22d116a83c6b android.hardware.neuralnetworks@1.0::IPreparedModel
 1fb32361286b938d48a55c2539c846732afce0b99fe08590f556643125bc13d3 android.hardware.neuralnetworks@1.0::types
@@ -398,5 +398,6 @@
 1d4a5776614c08b5d794a5ec5ab04697260cbd4b3441d5935cd53ee71d19da02 android.hardware.radio@1.0::IRadioResponse
 271187e261b30c01a33011aea257c07a2d2f05b72943ebee89e973e997849973 android.hardware.radio@1.0::types
 1d19720d4fd38b1095f0f555a4bd92b3b12c9b1d0f560b0e9a474cd6dcc20db6 android.hardware.radio@1.2::IRadio
+e78cf871f9fd1c072874e481e06e18e2681763cf2aa38c1fd777d53bab4eb69b android.hardware.sensors@1.0::types
 1722ad002317b1fae1400de709e90f442d94ef22864e05f7a12af48c32e8edc8 android.hardware.usb@1.1::types
 29c8da7a13c40d488f569c812441d5754ee45bdcdb8ce6564f524b708d10a057 android.hardware.vibrator@1.1::types
diff --git a/drm/1.1/README.md b/drm/1.1/README.md
new file mode 100644
index 0000000..e88e6ab
--- /dev/null
+++ b/drm/1.1/README.md
@@ -0,0 +1,84 @@
+# VINTF Device Manifest
+
+In Android Pie, an `<fqname>` tag was introduced to be able to express multiple
+different versions of the same HAL in VINTF manifests (for DRM)
+in device manifest. For devices launching with previous versions of Android and
+upgrading to Android Pie, the device manifest must not use `<fqname>` to
+satisfy requirements for non-optional HALs, because older version of `libvintf`
+do not recognize it, causing errors during OTA update.
+
+Assuming that the HAL provides `@1.0::I*/default`,
+`@1.1::I*/clearkey` and `@1.1::I*/foo` instances:
+
+## Devices upgrading to Android Pie
+
+### `target-level=1` or `target-level=2`
+
+FCM (framework compatibility matrix) version 2 (released in Android Oreo MR1)
+requires DRM 1.0. If the new device manifest has Target FCM Version (i.e.
+`target-level`) 1 or 2, it should use the following snippet:
+
+```xml
+<hal format="hidl">
+    <name>android.hardware.drm</name>
+    <transport>hwbinder</transport>
+    <version>1.0</version>
+    <interface>
+        <name>ICryptoFactory</name>
+        <instance>default</instance>
+    </interface>
+    <interface>
+        <name>IDrmFactory</name>
+        <instance>default</instance>
+    </interface>
+    <fqname>@1.1::ICryptoFactory/clearkey</fqname>
+    <fqname>@1.1::IDrmFactory/clearkey</fqname>
+    <fqname>@1.1::ICryptoFactory/foo</fqname>
+    <fqname>@1.1::IDrmFactory/foo</fqname>
+</hal>
+```
+
+### `target-level=3`
+
+FCM (framework compatibility matrix) version 3 (released in Android Pie)
+requires DRM 1.1. If the new device manifest has Target FCM Version (i.e.
+`target-level`) 3, it should use the following snippet:
+
+
+```xml
+<hal format="hidl">
+    <name>android.hardware.drm</name>
+    <transport>hwbinder</transport>
+    <version>1.1</version>
+    <interface>
+        <name>ICryptoFactory</name>
+        <instance>clearkey</instance>
+        <instance>foo</instance>
+    </interface>
+    <interface>
+        <name>IDrmFactory</name>
+        <instance>clearkey</instance>
+        <instance>foo</instance>
+    </interface>
+    <fqname>@1.0::ICryptoFactory/default</fqname>
+    <fqname>@1.0::IDrmFactory/default</fqname>
+</hal>
+```
+
+## Devices launching with Android Pie
+If you have a new device launched with Android Pie (no OTA), both of the
+aforementioned snippets can be used. Besides, it is recommended to use the
+new, clearer format:
+
+```xml
+<hal format="hidl">
+    <name>android.hardware.drm</name>
+    <transport>hwbinder</transport>
+    <fqname>@1.0::ICryptoFactory/default</fqname>
+    <fqname>@1.0::IDrmFactory/default</fqname>
+    <fqname>@1.1::ICryptoFactory/clearkey</fqname>
+    <fqname>@1.1::IDrmFactory/clearkey</fqname>
+    <fqname>@1.1::ICryptoFactory/foo</fqname>
+    <fqname>@1.1::IDrmFactory/foo</fqname>
+</hal>
+```
diff --git a/gnss/1.0/IGnssMeasurementCallback.hal b/gnss/1.0/IGnssMeasurementCallback.hal
index d3489e6..2d44766 100644
--- a/gnss/1.0/IGnssMeasurementCallback.hal
+++ b/gnss/1.0/IGnssMeasurementCallback.hal
@@ -436,6 +436,10 @@
          * Carrier-to-noise density in dB-Hz, typically in the range [0, 63].
          * It contains the measured C/N0 value for the signal at the antenna port.
          *
+         * If a signal has separate components (e.g. Pilot and Data channels) and
+         * the receiver only processes one of the components, then the reported
+         * cN0DbHz reflects only the component that is processed.
+         *
          * This value is mandatory.
          */
         double cN0DbHz;
diff --git a/graphics/bufferqueue/2.0/Android.bp b/graphics/bufferqueue/2.0/Android.bp
new file mode 100644
index 0000000..5385f28
--- /dev/null
+++ b/graphics/bufferqueue/2.0/Android.bp
@@ -0,0 +1,27 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.graphics.bufferqueue@2.0",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "types.hal",
+        "IGraphicBufferProducer.hal",
+        "IProducerListener.hal",
+    ],
+    interfaces: [
+        "android.hardware.graphics.common@1.0",
+        "android.hardware.graphics.common@1.1",
+        "android.hardware.graphics.common@1.2",
+        "android.hidl.base@1.0",
+    ],
+    types: [
+        "ConnectionType",
+        "SlotIndex",
+        "Status",
+    ],
+    gen_java: true,
+}
+
diff --git a/graphics/bufferqueue/2.0/IGraphicBufferProducer.hal b/graphics/bufferqueue/2.0/IGraphicBufferProducer.hal
new file mode 100644
index 0000000..734c0b4
--- /dev/null
+++ b/graphics/bufferqueue/2.0/IGraphicBufferProducer.hal
@@ -0,0 +1,648 @@
+/*
+ * Copyright (C) 2018 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.graphics.bufferqueue@2.0;
+
+import android.hardware.graphics.common@1.2::HardwareBuffer;
+import android.hardware.graphics.common@1.2::HardwareBufferDescription;
+import android.hardware.graphics.common@1.2::Rect;
+
+import IProducerListener;
+
+/**
+ * Ref: frameworks/native/include/gui/IGraphicBufferProducer.h:
+ *      IGraphicBufferProducer
+ * This is a wrapper/wrapped HAL interface for the actual binder interface.
+ */
+interface IGraphicBufferProducer {
+    /**
+     * Sets the maximum number of buffers that can be dequeued at one time. If
+     * this method succeeds, any new buffer slots shall be both unallocated and
+     * owned by the buffer queue, i.e., they are not owned by the producer or
+     * the consumer. Calling this may cause some buffer slots to be emptied. If
+     * the caller is caching the contents of the buffer slots, it must empty
+     * that cache after calling this method.
+     *
+     * @p maxDequeuedBuffers must not be less than the number of currently
+     * dequeued buffer slots; otherwise, the returned @p status shall be
+     * `BAD_VALUE`.
+     *
+     * @p maxDequeuedBuffers must be at least 1 (inclusive), but at most
+     * (`NUM_BUFFER_SLOTS` - the minimum undequeued buffer count) (exclusive).
+     * The minimum undequeued buffer count can be obtained by calling
+     * `query(ANATIVEWINDOW_QUERY_MIN_UNDEQUEUED_BUFFERS)`.
+     *
+     * Before calling setMaxDequeuedBufferCount(), the caller must make sure
+     * that
+     *   - @p maxDequeuedBuffers is greater than or equal to 1.
+     *   - @p maxDequeuedBuffers is greater than or equal to the number of
+     *     currently dequeued buffer slots.
+     * If any of these conditions do not hold, or if the request to set the new
+     * maximum number of dequeued buffers cannot be accomplished for any other
+     * reasons, `BAD_VALUE` shall be returned in @p status.
+     *
+     * @param maxDequeuedBuffers The desired number of buffers that can be
+     *     dequeued at one time.
+     * @return status Status of the call.
+     */
+    setMaxDequeuedBufferCount(
+            int32_t maxDequeuedBuffers
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Assigns a newly created buffer to the given slot index. The client is
+     * expected to mirror the slot-to-buffer mapping so that it is not necessary
+     * to transfer a `HardwareBuffer` object for every dequeue operation.
+     *
+     * If @p slot is not a valid slot index corresponding to a dequeued buffer,
+     * the call shall fail with @p status set to `BAD_VALUE`.
+     *
+     * @param slot Slot index.
+     * @return status Status of the call.
+     * @return buffer New buffer associated to the given slot index.
+     */
+    requestBuffer(
+            int32_t slot
+        ) generates (
+            Status status,
+            HardwareBuffer buffer
+        );
+
+    /**
+     * Sets the async flag: whether the producer intends to asynchronously queue
+     * buffers without blocking. Typically this is used for triple-buffering
+     * and/or when the swap interval is set to zero.
+     *
+     * Enabling async mode may internally allocate an additional buffer to allow
+     * for the asynchronous behavior. If it is not enabled, queue/dequeue calls
+     * may block.
+     *
+     * Changing the async flag may affect the number of available slots. If the
+     * adjustment to the number of slots cannot be made, @p status shall be set
+     * to `BAD_VALUE`.
+     *
+     * @param async True if the asynchronous operation is desired; false
+     *     otherwise.
+     * @return status Status of the call.
+     */
+    setAsyncMode(
+            bool async
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Input data for dequeueBuffer() specifying desired attributes of a buffer
+     * to dequeue.
+     *
+     * This structure contains 4 fields from
+     * +llndk libnativewindow#AHardwareBuffer_Desc.
+     *
+     * The `width` and `height` parameters must be no greater than the minimum
+     * of `GL_MAX_VIEWPORT_DIMS` and `GL_MAX_TEXTURE_SIZE` (see:
+     * glGetIntegerv()). An error due to invalid dimensions may not be reported
+     * until updateTexImage() is called.
+     *
+     * If `width` and `height` are both zero, the default dimensions shall be
+     * used. If only one of `width` and `height` is zero, dequeueBuffer() shall
+     * return `BAD_VALUE` in `status`.
+     *
+     * If `format` is zero, the default format shall be used.
+     *
+     * `usage` shall be merged with the usage flags set from the consumer side.
+     *
+     * @sa +llndk libnativewindow#AHardwareBuffer_Desc.
+     */
+    struct DequeueBufferInput {
+        uint32_t width;
+        uint32_t height;
+        uint32_t format;
+        uint64_t usage;
+    };
+
+    /**
+     * Output data for dequeueBuffer().
+     *
+     * A `DequeueBufferOutput` object returned from dequeueBuffer() shall be
+     * valid if and only if `status` returned from the same call is `OK`.
+     */
+    struct DequeueBufferOutput {
+        /**
+         * The number of frames that have elapsed since the buffer was last
+         * queued.
+         */
+        uint64_t bufferAge;
+        /**
+         * Whether the client must call requestBuffer().
+         */
+        bool bufferNeedsReallocation;
+        /**
+         * Whether the client must discard the mirrored slot-to-buffer
+         * mapping.
+         */
+        bool releaseAllBuffers;
+        /**
+         * Fence associated with the buffer.
+         *
+         * If this is an empty fence, the buffer may be written immediately;
+         * otherwise, the buffer must not be written to until the fence signals.
+         */
+        Fence fence;
+    };
+
+    /**
+     * Requests a new buffer slot for the client to use. Ownership of the slot
+     * is transfered to the client, meaning that the server shall not use the
+     * contents of the buffer associated with that slot.
+     *
+     * On success, @p status shall be `OK`, and @p output shall contain valid
+     * information of the call. Otherwise, the contents of @p output are
+     * meaningless.
+     *
+     * The slot index returned in @p slot may or may not contain a buffer
+     * (client-side). If the slot is empty, the client must call
+     * requestBuffer() to assign a new buffer to that slot.
+     *
+     * Once the client is done filling this buffer, it is expected to transfer
+     * buffer ownership back to the server with either cancelBuffer() on
+     * the dequeued slot or to fill in the contents of its associated buffer
+     * contents and call queueBuffer().
+     *
+     * If dequeueBuffer() returns with `output.releaseAllBuffers` set to `true`,
+     * the client is expected to release all of the mirrored slot-to-buffer
+     * mappings.
+     *
+     * If dequeueBuffer() returns with `output.bufferNeedsReallocation` set to
+     * `true`, the client is expected to call requestBuffer() immediately.
+     *
+     * The returned `output.fence` shall be updated to hold the fence associated
+     * with the buffer. The contents of the buffer must not be overwritten until
+     * the fence signals. If the fence is an empty fence, the buffer may be
+     * written immediately.
+     *
+     * This call shall block until a buffer is available to be dequeued. If
+     * both the producer and consumer are controlled by the app, then this call
+     * can never block and shall return `WOULD_BLOCK` in @p status if no buffer
+     * is available.
+     *
+     * If a dequeue operation shall cause certain conditions on the number of
+     * buffers to be violated (such as the maximum number of dequeued buffers),
+     * @p status shall be set to `INVALID_OPERATION` to indicate failure.
+     *
+     * If a dequeue operation cannot be completed within the time period
+     * previously set by setDequeueTimeout(), the return @p status shall
+     * `TIMED_OUT`.
+     *
+     * See @ref DequeueBufferInput for more information on the @p input
+     * parameter.
+     *
+     * @param input See #DequeueBufferInput for more information.
+     * @param status Status of the call.
+     * @param slot Slot index.
+     * @param output See #DequeueBufferOutput for more information.
+     *
+     * @sa queueBuffer(), requestBuffer().
+     */
+    dequeueBuffer(
+            DequeueBufferInput input
+        ) generates (
+            Status status,
+            int32_t slot,
+            DequeueBufferOutput output
+        );
+
+    /**
+     * Attempts to remove all ownership of the buffer in the given slot from the
+     * buffer queue.
+     *
+     * If this call succeeds, the slot shall be freed, and there shall be no way
+     * to obtain the buffer from this interface. The freed slot shall remain
+     * unallocated until either it is selected to hold a freshly allocated
+     * buffer in dequeueBuffer() or a buffer is attached to the slot. The buffer
+     * must have already been dequeued, and the caller must already possesses
+     * the buffer (i.e., must have called requestBuffer()).
+     *
+     * @param slot Slot index.
+     * @return status Status of the call.
+     */
+    detachBuffer(
+            int32_t slot
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Dequeues a buffer slot, requests the buffer associated to the slot, and
+     * detaches it from the buffer queue. This is equivalent to calling
+     * dequeueBuffer(), requestBuffer(), and detachBuffer() in succession except
+     * for two things:
+     *   1. It is unnecessary to provide a #DequeueBufferInput object.
+     *   2. The call shall not block, since if it cannot find an appropriate
+     *      buffer to return, it shall return an error instead.
+     *
+     * Only slots that are free but still contain a buffer shall be considered,
+     * and the oldest of those shall be returned. @p buffer is equivalent to the
+     * buffer that would be returned from requestBuffer(), and @p fence is
+     * equivalent to the fence that would be returned from dequeueBuffer().
+     *
+     * @return status Status of the call.
+     * @return buffer Buffer just released from the buffer queue.
+     * @return fence Fence associated to @p buffer.
+     *
+     * @sa dequeueBuffer(), requestBuffer(), detachBuffer().
+     */
+    detachNextBuffer(
+        ) generates (
+            Status status,
+            HardwareBuffer buffer,
+            Fence fence
+        );
+
+    /**
+     * Attempts to transfer ownership of a buffer to the buffer queue.
+     *
+     * If this call succeeds, it shall be as if this buffer was dequeued from the
+     * returned slot index. As such, this call shall fail if attaching this
+     * buffer would cause too many buffers to be simultaneously dequeued.
+     *
+     * If the returned @p releaseAllBuffers is `true`, the caller is expected to
+     * release all of the mirrored slot-to-buffer mappings.
+     *
+     * See dequeueBuffer() for conditions that may cause the call to fail.
+     *
+     * @param buffer Buffer to attach to the buffer queue.
+     * @return status Status of the call.
+     * @return slot Slot index assigned to @p buffer.
+     * @return releaseAllBuffers Whether the caller is expected to release all
+     *     of the mirrored slot-to-buffer mappings.
+     *
+     * @sa dequeueBuffer().
+     */
+    attachBuffer(
+            HardwareBuffer buffer
+        ) generates (
+            Status status,
+            int32_t slot,
+            bool releaseAllBuffers
+        );
+
+    struct QueueBufferInput {
+        /**
+         * Timestamp in nanoseconds.
+         */
+        int64_t timestamp;
+        /**
+         * Whether the timestamp was synthesized at queue time.
+         */
+        bool isAutoTimestamp;
+        /**
+         * Dataspace of the contents.
+         *
+         * @sa +ndk libnativewindow#ADataSpace.
+         */
+        int32_t dataSpace;
+        /**
+         * Crop rectangle that is used as a hint to the consumer.
+         */
+        Rect crop;
+        /**
+         * Transformation flags.
+         *
+         * @sa +ndk libnativewindow#ANativeWindowTransform.
+         */
+        int32_t transform;
+        /**
+         * The sticky transform set in Surface (only used by the LEGACY camera
+         * mode).
+         *
+         * @sa +ndk libnativewindow#ANativeWindowTransform.
+         */
+        int32_t stickyTransform;
+        /**
+         * Fence that the consumer must wait on before reading the buffer. An
+         * empty fence indicates that the buffer is ready immediately.
+         */
+        Fence fence;
+        /**
+         * List of rectangular pieces covering the damage region.
+         */
+        vec<Rect> surfaceDamage;
+    };
+
+    /**
+     * Information about the queued buffer. `QueueBufferOutput` is used in both
+     * queueBuffer() and connect().
+     */
+    struct QueueBufferOutput {
+        /**
+         * Default width of a buffer in the buffer queue.
+         */
+        uint32_t width;
+        /**
+         * Default height of a buffer in the buffer queue.
+         */
+        uint32_t height;
+        /**
+         * The transform hint of the buffer queue.
+         *
+         * @sa +ndk libnativewindow#ANativeWindowTransform.
+         */
+        int32_t transformHint;
+        /**
+         * The number of pending buffers in the buffer queue. If this is
+         * returned from queueBuffer(), the number shall include the buffer that
+         * has just been queued.
+         */
+        uint32_t numPendingBuffers;
+        /**
+         * The frame number of the next frame. The buffer queue maintains this
+         * number and makes sure that it is increasing for every successful
+         * queueBuffer() call.
+         */
+        uint64_t nextFrameNumber;
+        /**
+         * After a successful queueBuffer() call, #bufferReplaced shall be set to
+         * true if the queued buffer replaced a previously queued buffer that
+         * has not been consumed.
+         */
+        bool bufferReplaced;
+    };
+
+    /**
+     * Indicates that the client has finished filling in the contents of the
+     * buffer associated with slot and transfers ownership of that slot back to
+     * the buffer queue.
+     *
+     * @p status may be set to `BAD_VALUE` if any of the following conditions
+     * hold:
+     *   - The buffer queue is operating in the asynchronous mode, and the
+     *     buffer count was smaller than the maximum number of buffers that can
+     *     be allocated at once.
+     *   - @p slot is an invalid slot index, i.e., the slot is not owned by the
+     *     client by previously calling dequeueBuffer(), requestBuffer() or
+     *     attachBuffer().
+     *   - The crop rectangle is not contained in the buffer.
+     *
+     * Upon success, the output shall be filled with meaningful values
+     * (refer to the documentation of @ref QueueBufferOutput).
+     *
+     * @param slot Slot index.
+     * @param input See @ref QueueBufferInput.
+     * @return status Status of the call.
+     * @return output See @ref QueueBufferOutput.
+     *
+     * @sa #QueueBufferInput, #QueueBufferOutput, dequeueBuffer().
+     */
+    queueBuffer(
+            int32_t slot,
+            QueueBufferInput input
+        ) generates (
+            Status status,
+            QueueBufferOutput output
+        );
+
+    /**
+     * Indicates that the client does not wish to fill in the buffer associated
+     * with the slot and transfers ownership of the slot back to the server. The
+     * buffer is not queued for use by the consumer.
+     *
+     * If @p fence is not an empty fence, the buffer shall not be overwritten
+     * until the fence signals. @p fence is usually obtained from
+     * dequeueBuffer().
+     *
+     * @param slot Slot index.
+     * @param fence Fence for the canceled buffer.
+     * @return status Status of the call.
+     */
+    cancelBuffer(
+            int32_t slot,
+            Fence fence
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Retrieves information for this surface.
+     *
+     * @param what What to query. @p what must be one of the values in
+     *     +llndk libnativewindow#ANativeWindowQuery.
+     * @return status Status of the call.
+     * @return value The value queried. The set of possible values depends on
+     *     the value of @p what.
+     *
+     * @sa +llndk libnativewindow#ANativeWindowQuery.
+     */
+    query(
+            int32_t what
+        ) generates (
+            int32_t result,
+            int32_t value
+        );
+
+    /**
+     * Attempts to connect the client as a producer of the buffer queue.
+     * This method must be called before any other methods in this interface.
+     *
+     * If the buffer queue does not have a consumer ready (connected), the
+     * return @p status shall be `NO_INIT`.
+     *
+     * If any of the following conditions hold, the error code `BAD_VALUE` shall
+     * be reported in @p status:
+     *   - The producer is already connected.
+     *   - The number of available slots cannot be adjusted to accommodate the
+     *     supplied value of @p producerControlledByApp.
+     *
+     * @param listener An optional callback object that can be provided if the
+     *     client wants to be notified when the consumer releases a buffer back
+     *     to the buffer queue.
+     * @param api How the client shall write to buffers.
+     * @param producerControlledByApp `true` if the producer is hosted by an
+     *     untrusted process (typically application-forked processes). If both
+     *     the producer and the consumer are controlled by app, the buffer queue
+     *     shall operate in the asynchronous mode regardless of the async flag
+     *     set by setAsyncMode().
+     * @return status Status of the call.
+     * @return output See #QueueBufferOutput for more information.
+     *
+     * @sa #QueueBufferOutput, disconnect(), setAsyncMode().
+     */
+    connect(
+            IProducerListener listener,
+            ConnectionType api,
+            bool producerControlledByApp
+        ) generates (
+            Status status,
+            QueueBufferOutput output
+        );
+
+    /**
+     * Attempts to disconnect the client from the producer end of the buffer
+     * queue.
+     *
+     * Calling this method shall cause any subsequent calls to other
+     * @ref IGraphicBufferProducer methods apart from connect() to fail.
+     * A successful connect() call afterwards may allow other methods to succeed
+     * again.
+     *
+     * Disconnecting from an abandoned buffer queue is legal and is considered a
+     * no-op.
+     *
+     * @param api The type of connection to disconnect. Supplying the value of
+     *     `CURRENTLY_CONNECTED` to @p api has the same effect as supplying the
+     *     current connection type. If the producer end is not connected,
+     *     supplying `CURRENTLY_CONNECTED` shall result in a successful no-op
+     *     call.
+     * @return status Status of the call.
+     *
+     * @sa connect().
+     */
+    disconnect(
+            ConnectionType api
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Allocates buffers based on the given dimensions, format and usage.
+     *
+     * This function shall allocate up to the maximum number of buffers
+     * permitted by the current buffer queue configuration. It shall use the
+     * given format, dimensions, and usage bits, which are interpreted in the
+     * same way as for dequeueBuffer(), and the async flag must be set the same
+     * way as for dequeueBuffer() to ensure that the correct number of buffers
+     * are allocated. This is most useful to avoid an allocation delay during
+     * dequeueBuffer(). If there are already the maximum number of buffers
+     * allocated, this function has no effect.
+     *
+     * A value of 0 in @p width, @p height or @p format indicates that the
+     * buffer queue can pick the default value.
+     *
+     * @param width Width of buffers to allocate.
+     * @param height Height of buffers to allocate.
+     * @param format Format of buffers to allocate.
+     * @param usage Usage of bufferes to allocate.
+     * @return status Status of the call.
+     */
+    allocateBuffers(
+            uint32_t width,
+            uint32_t height,
+            uint32_t format,
+            uint64_t usage
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Sets whether dequeueBuffer() is allowed to allocate new buffers.
+     *
+     * Normally dequeueBuffer() does not discriminate between free slots which
+     * already have an allocated buffer and those which do not, and shall
+     * allocate a new buffer if the slot doesn't have a buffer or if the slot's
+     * buffer doesn't match the requested size, format, or usage. This method
+     * allows the producer to restrict the eligible slots to those which already
+     * have an allocated buffer of the correct size, format, and usage. If no
+     * eligible slot is available, dequeueBuffer() shall block or return an
+     * error.
+     *
+     * @param allow Whether to allow new buffers to be allocated in
+     *     dequeueBuffer().
+     * @return status Status of the call.
+     */
+    allowAllocation(
+            bool allow
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Sets the current generation number of the buffer queue.
+     *
+     * This generation number shall be inserted into any buffers allocated by the
+     * buffer queue, and any attempts to attach a buffer with a different
+     * generation number shall fail. Buffers already in the queue are not
+     * affected and shall retain their current generation number. The generation
+     * number defaults to 0, i.e., buffers allocated before the first call to
+     * setGenerationNumber() shall be given 0 as their generation numbers.
+     *
+     * @param generationNumber New generation number. The client must make sure
+     *     that @p generationNumber is different from the previous generation
+     *     number if it wants to deprecate old buffers.
+     * @return status Status of the call.
+     */
+    setGenerationNumber(
+            uint32_t generationNumber
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Sets how long dequeueBuffer() shall wait for a buffer to become available
+     * before returning an error `TIMED_OUT`.
+     *
+     * This timeout also affects the attachBuffer() call, which shall block if
+     * there is not a free slot available into which the attached buffer can be
+     * placed.
+     *
+     * By default, the buffer queue shall wait forever, which is equivalent to
+     * setting @p timeoutNs equal to any negative number (such as `-1`). If
+     * @p timeoutNs is non-negative, setDequeueTimeout() shall disable
+     * non-blocking mode and its corresponding spare buffer (which is used to
+     * ensure a buffer is always available).
+     *
+     * Changing the dequeue timeout may affect the number of buffers. (See
+     * setAsyncMode().) If the adjustment to the number of buffers inside the
+     * buffer queue is not feasible, @p status shall be set to `BAD_VALUE`.
+     *
+     * @param timeoutNs Amount of time dequeueBuffer() is allowed to block
+     *     before returning `TIMED_OUT`. If @p timeoutNs is negative,
+     *     dequeueBuffer() shall not be able to return `TIMED_OUT`. Instead, it
+     *     may block forever or return `WOULD_BLOCK`.
+     * @return status Status of the call.
+     *
+     * @sa dequeueBuffer(), setAsyncMode(), query().
+     */
+    setDequeueTimeout(
+            int64_t timeoutNs
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Returns a unique id for this buffer queue.
+     *
+     * @return id System-wide unique id of the buffer queue.
+     */
+    getUniqueId(
+        ) generates (
+            uint64_t id
+        );
+
+    /**
+     * Returns the name of the connected consumer.
+     *
+     * \note This is used for debugging only.
+     *
+     * @return name Name of the consumer.
+     */
+    getConsumerName(
+        ) generates (
+            string name
+        );
+
+};
+
diff --git a/graphics/bufferqueue/2.0/IProducerListener.hal b/graphics/bufferqueue/2.0/IProducerListener.hal
new file mode 100644
index 0000000..bc478ed
--- /dev/null
+++ b/graphics/bufferqueue/2.0/IProducerListener.hal
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 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.graphics.bufferqueue@2.0;
+
+/**
+ * Listener interface.
+ */
+interface IProducerListener {
+    /**
+     * Notifies the listener when buffers are released.
+     *
+     * This function is usually called by the consumer.
+     *
+     * @param count The number of buffers released (since the last call to
+     *     onBufferReleased()).
+     */
+    oneway onBuffersReleased(uint32_t count);
+};
+
diff --git a/graphics/bufferqueue/2.0/types.hal b/graphics/bufferqueue/2.0/types.hal
new file mode 100644
index 0000000..f6bc2d9
--- /dev/null
+++ b/graphics/bufferqueue/2.0/types.hal
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2018 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.graphics.bufferqueue@2.0;
+
+/**
+ * Possible return values from a function call.
+ */
+enum Status : int32_t {
+    /**
+     * The call succeeds.
+     */
+    OK = 0,
+    /**
+     * The function fails allocate memory.
+     */
+    NO_MEMORY = -12,
+    /**
+     * The buffer queue has been abandoned, no consumer is connected, or no
+     * producer is connected at the time of the call.
+     */
+    NO_INIT = -19,
+    /**
+     * Some of the provided input arguments are invalid.
+     */
+    BAD_VALUE = -22,
+    /**
+     * An unexpected death of some object prevents the operation from
+     * continuing.
+     *
+     * @note This status value is different from a transaction failure, which
+     * should be detected by isOk().
+     */
+    DEAD_OBJECT = -32,
+    /**
+     * The internal state of the buffer queue does not permit the operation.
+     */
+    INVALID_OPERATION = -38,
+    /**
+     * The call fails to finish within the specified time limit.
+     */
+    TIMED_OUT = -110,
+    /**
+     * The buffer queue is operating in a non-blocking mode, but the call cannot
+     * be completed without blocking.
+     */
+    WOULD_BLOCK = 0xfffffffb,
+    /**
+     * The call fails because of a reason not listed above.
+     */
+    UNKNOWN_ERROR = 0xffffffff,
+};
+
+/**
+ * Special values for a slot index.
+ */
+enum SlotIndex : int32_t {
+    /**
+     * Invalid/unspecified slot index. This may be returned from a function that
+     * returns a slot index if the call is unsuccessful.
+     */
+    INVALID = -1,
+    UNSPECIFIED = -1,
+};
+
+/**
+ * An "empty" fence can be an empty handle (containing no fds and no ints) or a
+ * fence with one fd that is equal to -1 and no ints.
+ *
+ * A valid fence is an empty fence or a native handle with exactly one fd and no
+ * ints.
+ */
+typedef handle Fence;
+
+/**
+ * How buffers shall be produced. One of these values must be provided in a call
+ * to IGraphicBufferProducer::connect() and
+ * IGraphicBufferProducer::disconnect().
+ */
+enum ConnectionType : int32_t {
+    /**
+     * This value can be used only as an input to
+     * IGraphicBufferProducer::disconnect().
+     */
+    CURRENTLY_CONNECTED = -1,
+    /**
+     * Buffers shall be queued by EGL via `eglSwapBuffers()` after being filled
+     * using OpenGL ES.
+     */
+    EGL = 1,
+    /**
+     * Buffers shall be queued after being filled using the CPU.
+     */
+    CPU = 2,
+    /**
+     * Buffers shall be queued by Stagefright after being filled by a video
+     * decoder. The video decoder can either be a software or hardware decoder.
+     */
+    MEDIA = 3,
+    /**
+     * Buffers shall be queued by the camera HAL.
+     */
+    CAMERA = 4,
+};
+
+
diff --git a/graphics/common/1.2/Android.bp b/graphics/common/1.2/Android.bp
index a86f3b5..a3ebdbf 100644
--- a/graphics/common/1.2/Android.bp
+++ b/graphics/common/1.2/Android.bp
@@ -15,7 +15,9 @@
         "android.hardware.graphics.common@1.1",
     ],
     types: [
+        "ColorMode",
         "Dataspace",
+        "HardwareBuffer",
     ],
     gen_java: true,
     gen_java_constants: true,
diff --git a/graphics/common/1.2/types.hal b/graphics/common/1.2/types.hal
index cf4e34a..15f2c14 100644
--- a/graphics/common/1.2/types.hal
+++ b/graphics/common/1.2/types.hal
@@ -51,3 +51,39 @@
      */
     DISPLAY_BT2020 = 13,
 };
+
+/**
+ * HIDL counterpart of `AHardwareBuffer_Desc`.
+ *
+ * An `AHardwareBuffer_Desc` object can be converted to and from a
+ * `HardwareBufferDescription` object by `memcpy()`.
+ *
+ * @sa +ndk libnativewindow#AHardwareBuffer_Desc.
+ */
+typedef uint32_t[10] HardwareBufferDescription;
+
+/**
+ * HIDL counterpart of `AHardwareBuffer`.
+ *
+ * AHardwareBuffer_createFromHandle() can be used to convert a `HardwareBuffer`
+ * object to an `AHardwareBuffer` object.
+ *
+ * Conversely, AHardwareBuffer_getNativeHandle() can be used to extract a native
+ * handle from an `AHardwareBuffer` object. Paired with `AHardwareBuffer_Desc`,
+ * AHardwareBuffer_getNativeHandle() can be used to convert between
+ * `HardwareBuffer` and `AHardwareBuffer`.
+ *
+ * @sa +ndk libnativewindow#AHardwareBuffer".
+ */
+struct HardwareBuffer {
+    HardwareBufferDescription description;
+    handle nativeHandle;
+};
+
+/**
+ * HIDL counterpart of `ARect`.
+ *
+ * @sa +ndk libarect_headers#ARect.
+ */
+typedef int32_t[4] Rect;
+
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h
index 2cbf044..f249f1a 100644
--- a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h
@@ -186,6 +186,8 @@
         : mBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, bufferCacheSize),
           mSidebandStreamCache(importer, ComposerHandleCache::HandleType::STREAM, 1) {}
 
+    virtual ~ComposerLayerResource() = default;
+
     Error getBuffer(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
                     const native_handle_t** outHandle, const native_handle** outReplacedHandle) {
         return mBufferCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
@@ -211,6 +213,8 @@
         VIRTUAL,
     };
 
+    virtual ~ComposerDisplayResource() = default;
+
     ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
                             uint32_t outputBufferCacheSize)
         : mType(type),
diff --git a/graphics/composer/2.3/IComposerClient.hal b/graphics/composer/2.3/IComposerClient.hal
index dec3b25..7856658 100644
--- a/graphics/composer/2.3/IComposerClient.hal
+++ b/graphics/composer/2.3/IComposerClient.hal
@@ -161,6 +161,116 @@
                                Dataspace dataspace)
                     generates (Error error);
 
+    enum FormatColorComponent : uint8_t {
+        /* The first component  (eg, for RGBA_8888, this is R) */
+        FORMAT_COMPONENT_0 = 1 << 0,
+        /* The second component (eg, for RGBA_8888, this is G) */
+        FORMAT_COMPONENT_1 = 1 << 1,
+        /* The third component  (eg, for RGBA_8888, this is B) */
+        FORMAT_COMPONENT_2 = 1 << 2,
+        /* The fourth component (eg, for RGBA_8888, this is A) */
+        FORMAT_COMPONENT_3 = 1 << 3,
+    };
+
+    /**
+     * Query for what types of color sampling the hardware supports.
+     *
+     * @param  display        is the display where the samples are collected.
+     * @return error          is NONE upon success. Otherwise,
+     *                        BAD_DISPLAY when an invalid display was passed in, or
+     *                        UNSUPPORTED when there is no efficient way to sample.
+     * @return format         The format of the sampled pixels.
+     * @return dataspace      The dataspace of the sampled pixels.
+     * @return componentMask  The mask of which components can be sampled.
+     */
+    getDisplayedContentSamplingAttributes(Display display)
+               generates (Error error,
+                          PixelFormat format,
+                          Dataspace dataspace,
+                          bitfield<FormatColorComponent> componentMask);
+
+    /** DisplayedContentSampling values passed to setDisplayedContentSamplingEnabled. */
+    enum DisplayedContentSampling : int32_t {
+        INVALID = 0,
+
+        /** Enable content sampling. */
+        ENABLE = 1,
+
+        /** Disable content sampling. */
+        DISABLE = 2,
+    };
+
+    /**
+     * Enables or disables the collection of color content statistics
+     * on this display.
+     *
+     * Sampling occurs on the contents of the final composition on this display
+     * (i.e., the contents presented on screen). Samples should be collected after all
+     * color transforms have been applied.
+     *
+     * Sampling support is optional, and is set to DISABLE by default.
+     * On each call to ENABLE, all collected statistics must be reset.
+     *
+     * Sample data can be queried via getDisplayedContentSample().
+     *
+     * @param display        is the display to which the sampling mode is set.
+     * @param enabled        indicates whether to enable or disable sampling.
+     * @param componentMask  The mask of which components should be sampled. If zero, all supported
+     *                       components are to be enabled.
+     * @param maxFrames      is the maximum number of frames that should be stored before discard.
+     *                       The sample represents the most-recently posted frames.
+     * @return error      is NONE upon success. Otherwise,
+     *                    BAD_DISPLAY when an invalid display handle was passed in,
+     *                    BAD_PARAMETER when enabled was an invalid value, or
+     *                    NO_RESOURCES when the requested ringbuffer size via maxFrames was
+     *                                 not available.
+     *                    UNSUPPORTED when there is no efficient way to sample.
+     */
+    setDisplayedContentSamplingEnabled(
+        Display display, DisplayedContentSampling enable,
+        bitfield<FormatColorComponent> componentMask, uint64_t maxFrames)
+        generates (Error error);
+
+    /**
+     * Collects the results of display content color sampling for display.
+     *
+     * Collection of data can occur whether the sampling is in ENABLE or
+     * DISABLE state.
+     *
+     * @param  display     is the display to which the sampling is collected.
+     * @param  maxFrames   is the maximum number of frames that should be represented in the sample.
+     *                     The sample represents the most-recently posted frames.
+     *                     If maxFrames is 0, all frames are to be represented by the sample.
+     * @param  timestamp   is the timestamp after which any frames were posted that should be
+     *                     included in the sample. Timestamp is CLOCK_MONOTONIC.
+     *                     If timestamp is 0, do not filter from the sample by time.
+     * @return error       is NONE upon success. Otherwise,
+     *                     BAD_DISPLAY   when an invalid display was passed in, or
+     *                     UNSUPPORTED   when there is no efficient way to sample, or
+     *                     BAD_PARAMETER when the component is not supported by the hardware.
+     * @return frameCount  The number of frames represented by this sample.
+     * @return sampleComponent0 is a histogram counting how many times a pixel of a given value
+     *                     was displayed onscreen for FORMAT_COMPONENT_0.
+     *                     The buckets of the histogram are evenly weighted, the number of buckets
+     *                     is device specific.
+     *                     eg, for RGBA_8888, if sampleComponent0 is {10, 6, 4, 1} this means that
+     *                     10 red pixels were displayed onscreen in range 0x00->0x3F, 6 red pixels
+     *                     were displayed onscreen in range 0x40->0x7F, etc.
+     * @return sampleComponent1 is the same sample definition as sampleComponent0,
+     *                     but for FORMAT_COMPONENT_1.
+     * @return sampleComponent2 is the same sample definition as sampleComponent0,
+     *                     but for FORMAT_COMPONENT_2.
+     * @return sampleComponent3 is the same sample definition as sampleComponent0,
+     *                     but for FORMAT_COMPONENT_3.
+     */
+    getDisplayedContentSample(Display display, uint64_t maxFrames, uint64_t timestamp)
+               generates (Error error,
+                          uint64_t frameCount,
+                          vec<uint64_t> sampleComponent0,
+                          vec<uint64_t> sampleComponent1,
+                          vec<uint64_t> sampleComponent2,
+                          vec<uint64_t> sampleComponent3);
+
     /**
      * Executes commands from the input command message queue. Return values
      * generated by the input commands are written to the output command
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
index 90603a7..be0ef4c 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
@@ -39,25 +39,14 @@
 class ComposerClientImpl : public V2_2::hal::detail::ComposerClientImpl<Interface, Hal> {
    public:
     Return<Error> setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) override {
-#ifndef USES_DISPLAY_RENDER_INTENTS
-        if (intent != RenderIntent::COLORIMETRIC) {
-            return Error::BAD_PARAMETER;
-        }
-#endif
         return mHal->setColorMode_2_3(display, mode, intent);
     }
 
     Return<void> getRenderIntents_2_3(Display display, ColorMode mode,
                                       IComposerClient::getRenderIntents_2_3_cb hidl_cb) override {
-#ifdef USES_DISPLAY_RENDER_INTENTS
         std::vector<RenderIntent> intents;
         Error err = mHal->getRenderIntents_2_3(display, mode, &intents);
         hidl_cb(err, intents);
-#else
-        (void)display;
-        (void)mode;
-        hidl_cb(Error::NONE, hidl_vec<RenderIntent>({RenderIntent::COLORIMETRIC}));
-#endif
         return Void();
     }
 
@@ -102,6 +91,42 @@
         return Void();
     }
 
+    Return<void> getDisplayedContentSamplingAttributes(
+        uint64_t display,
+        IComposerClient::getDisplayedContentSamplingAttributes_cb hidl_cb) override {
+        common::V1_1::PixelFormat format;
+        common::V1_2::Dataspace dataspace;
+        hidl_bitfield<IComposerClient::FormatColorComponent> componentMask;
+        Error error =
+            mHal->getDisplayedContentSamplingAttributes(display, format, dataspace, componentMask);
+        hidl_cb(error, format, dataspace, componentMask);
+        return Void();
+    }
+
+    Return<Error> setDisplayedContentSamplingEnabled(
+        uint64_t display, IComposerClient::DisplayedContentSampling enable,
+        hidl_bitfield<IComposerClient::FormatColorComponent> componentMask,
+        uint64_t maxFrames) override {
+        return mHal->setDisplayedContentSamplingEnabled(display, enable, componentMask, maxFrames);
+    }
+
+    Return<void> getDisplayedContentSample(
+        uint64_t display, uint64_t maxFrames, uint64_t timestamp,
+        IComposerClient::getDisplayedContentSample_cb hidl_cb) override {
+        uint64_t frameCount;
+        hidl_vec<uint64_t> sampleComponent0;
+        hidl_vec<uint64_t> sampleComponent1;
+        hidl_vec<uint64_t> sampleComponent2;
+        hidl_vec<uint64_t> sampleComponent3;
+
+        Error error = mHal->getDisplayedContentSample(display, maxFrames, timestamp, frameCount,
+                                                      sampleComponent0, sampleComponent1,
+                                                      sampleComponent2, sampleComponent3);
+        hidl_cb(error, frameCount, sampleComponent0, sampleComponent1, sampleComponent2,
+                sampleComponent3);
+        return Void();
+    }
+
     Return<void> executeCommands_2_3(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles,
                                      IComposerClient::executeCommands_2_2_cb hidl_cb) override {
         std::lock_guard<std::mutex> lock(mCommandEngineMutex);
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
index 27efc2b..8ca5d75 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
@@ -72,6 +72,18 @@
     virtual Error getDisplayIdentificationData(Display display, uint8_t* outPort,
                                                std::vector<uint8_t>* outData) = 0;
     virtual Error setLayerColorTransform(Display display, Layer layer, const float* matrix) = 0;
+    virtual Error getDisplayedContentSamplingAttributes(
+        uint64_t display, PixelFormat& format, Dataspace& dataspace,
+        hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask) = 0;
+    virtual Error setDisplayedContentSamplingEnabled(
+        uint64_t display, IComposerClient::DisplayedContentSampling enable,
+        hidl_bitfield<IComposerClient::FormatColorComponent> componentMask, uint64_t maxFrames) = 0;
+    virtual Error getDisplayedContentSample(uint64_t display, uint64_t maxFrames,
+                                            uint64_t timestamp, uint64_t& frameCount,
+                                            hidl_vec<uint64_t>& sampleComponent0,
+                                            hidl_vec<uint64_t>& sampleComponent1,
+                                            hidl_vec<uint64_t>& sampleComponent2,
+                                            hidl_vec<uint64_t>& sampleComponent3) = 0;
 };
 
 }  // namespace hal
diff --git a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
index df68f58..8d444c8 100644
--- a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
+++ b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
@@ -104,6 +104,65 @@
         return static_cast<Error>(err);
     }
 
+    Error getDisplayedContentSamplingAttributes(
+        uint64_t display, PixelFormat& format, Dataspace& dataspace,
+        hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask) override {
+        if (!mDispatch.getDisplayedContentSamplingAttributes) {
+            return Error::UNSUPPORTED;
+        }
+        int32_t formatRaw = 0;
+        int32_t dataspaceRaw = 0;
+        uint8_t componentMaskRaw = 0;
+        int32_t errorRaw = mDispatch.getDisplayedContentSamplingAttributes(
+            mDevice, display, &formatRaw, &dataspaceRaw, &componentMaskRaw);
+        auto error = static_cast<Error>(errorRaw);
+        if (error == Error::NONE) {
+            format = static_cast<PixelFormat>(formatRaw);
+            dataspace = static_cast<Dataspace>(dataspaceRaw);
+            componentMask =
+                static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(componentMaskRaw);
+        }
+        return error;
+    };
+
+    Error setDisplayedContentSamplingEnabled(
+        uint64_t display, IComposerClient::DisplayedContentSampling enable,
+        hidl_bitfield<IComposerClient::FormatColorComponent> componentMask,
+        uint64_t maxFrames) override {
+        if (!mDispatch.setDisplayedContentSamplingEnabled) {
+            return Error::UNSUPPORTED;
+        }
+        return static_cast<Error>(mDispatch.setDisplayedContentSamplingEnabled(
+            mDevice, display, static_cast<int32_t>(enable), componentMask, maxFrames));
+    }
+
+    Error getDisplayedContentSample(uint64_t display, uint64_t maxFrames, uint64_t timestamp,
+                                    uint64_t& frameCount, hidl_vec<uint64_t>& sampleComponent0,
+                                    hidl_vec<uint64_t>& sampleComponent1,
+                                    hidl_vec<uint64_t>& sampleComponent2,
+                                    hidl_vec<uint64_t>& sampleComponent3) override {
+        if (!mDispatch.getDisplayedContentSample) {
+            return Error::UNSUPPORTED;
+        }
+
+        int32_t size[4] = {0};
+        auto errorRaw = mDispatch.getDisplayedContentSample(mDevice, display, maxFrames, timestamp,
+                                                            &frameCount, size, nullptr);
+        if (errorRaw != HWC2_ERROR_NONE) {
+            return static_cast<Error>(errorRaw);
+        }
+
+        sampleComponent0.resize(size[0]);
+        sampleComponent1.resize(size[1]);
+        sampleComponent2.resize(size[2]);
+        sampleComponent3.resize(size[3]);
+        uint64_t* samples[] = {sampleComponent0.data(), sampleComponent1.data(),
+                               sampleComponent2.data(), sampleComponent3.data()};
+        errorRaw = mDispatch.getDisplayedContentSample(mDevice, display, maxFrames, timestamp,
+                                                       &frameCount, size, samples);
+        return static_cast<Error>(errorRaw);
+    }
+
    protected:
     bool initDispatch() override {
         if (!BaseType2_2::initDispatch()) {
@@ -114,6 +173,12 @@
                                    &mDispatch.getDisplayIdentificationData);
         this->initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_COLOR_TRANSFORM,
                                    &mDispatch.setLayerColorTransform);
+        this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES,
+                                   &mDispatch.getDisplayedContentSamplingAttributes);
+        this->initOptionalDispatch(HWC2_FUNCTION_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED,
+                                   &mDispatch.setDisplayedContentSamplingEnabled);
+        this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAYED_CONTENT_SAMPLE,
+                                   &mDispatch.getDisplayedContentSample);
         return true;
     }
 
@@ -121,6 +186,9 @@
     struct {
         HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA getDisplayIdentificationData;
         HWC2_PFN_SET_LAYER_COLOR_TRANSFORM setLayerColorTransform;
+        HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES getDisplayedContentSamplingAttributes;
+        HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED setDisplayedContentSamplingEnabled;
+        HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE getDisplayedContentSample;
     } mDispatch = {};
 
     using BaseType2_2 = V2_2::passthrough::detail::HwcHalImpl<Hal>;
diff --git a/graphics/composer/2.3/utils/vts/ComposerVts.cpp b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
index 656c8c4..9304992 100644
--- a/graphics/composer/2.3/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
@@ -108,6 +108,48 @@
     return error == Error::NONE;
 }
 
+Error ComposerClient::getDisplayedContentSamplingAttributes(
+    uint64_t display, PixelFormat& format, Dataspace& dataspace,
+    hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask) {
+    auto error = Error::BAD_PARAMETER;
+    mClient->getDisplayedContentSamplingAttributes(
+        display, [&](const auto& tmpError, const auto& tmpFormat, const auto& tmpDataspace,
+                     const auto& tmpComponentMask) {
+            error = tmpError;
+            format = tmpFormat;
+            dataspace = tmpDataspace;
+            componentMask = tmpComponentMask;
+        });
+    return error;
+}
+
+Error ComposerClient::setDisplayedContentSamplingEnabled(
+    uint64_t display, IComposerClient::DisplayedContentSampling enable,
+    hidl_bitfield<IComposerClient::FormatColorComponent> componentMask, uint64_t maxFrames) {
+    return mClient->setDisplayedContentSamplingEnabled(display, enable, componentMask, maxFrames);
+}
+
+Error ComposerClient::getDisplayedContentSample(uint64_t display, uint64_t maxFrames,
+                                                uint64_t timestamp, uint64_t& frameCount,
+                                                hidl_vec<uint64_t>& sampleComponent0,
+                                                hidl_vec<uint64_t>& sampleComponent1,
+                                                hidl_vec<uint64_t>& sampleComponent2,
+                                                hidl_vec<uint64_t>& sampleComponent3) {
+    auto error = Error::BAD_PARAMETER;
+    mClient->getDisplayedContentSample(
+        display, maxFrames, timestamp,
+        [&](const auto& tmpError, const auto& tmpFrameCount, const auto& tmpSamples0,
+            const auto& tmpSamples1, const auto& tmpSamples2, const auto& tmpSamples3) {
+            error = tmpError;
+            frameCount = tmpFrameCount;
+            sampleComponent0 = tmpSamples0;
+            sampleComponent1 = tmpSamples1;
+            sampleComponent2 = tmpSamples2;
+            sampleComponent3 = tmpSamples3;
+        });
+    return error;
+}
+
 }  // namespace vts
 }  // namespace V2_3
 }  // namespace composer
diff --git a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
index ec1a2a1..4b9c955 100644
--- a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
+++ b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
@@ -37,6 +37,7 @@
 using common::V1_2::ColorMode;
 using common::V1_2::Dataspace;
 using V2_1::Display;
+using V2_1::Error;
 using V2_3::IComposer;
 using V2_3::IComposerClient;
 
@@ -67,6 +68,17 @@
 
     bool getDisplayIdentificationData(Display display, uint8_t* outPort,
                                       std::vector<uint8_t>* outData);
+    Error getDisplayedContentSamplingAttributes(
+        uint64_t display, PixelFormat& format, Dataspace& dataspace,
+        hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask);
+    Error setDisplayedContentSamplingEnabled(
+        uint64_t display, IComposerClient::DisplayedContentSampling enable,
+        hidl_bitfield<IComposerClient::FormatColorComponent> componentMask, uint64_t maxFrames);
+    Error getDisplayedContentSample(uint64_t display, uint64_t maxFrames, uint64_t timestamp,
+                                    uint64_t& frameCount, hidl_vec<uint64_t>& sampleComponent0,
+                                    hidl_vec<uint64_t>& sampleComponent1,
+                                    hidl_vec<uint64_t>& sampleComponent2,
+                                    hidl_vec<uint64_t>& sampleComponent3);
 
     std::vector<ColorMode> getColorModes_2_3(Display display);
 
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index 3ca21aa..a294825 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -355,6 +355,78 @@
     execute();
 }
 
+TEST_F(GraphicsComposerHidlTest, GetDisplayedContentSamplingAttributes) {
+    using common::V1_1::PixelFormat;
+    using common::V1_2::Dataspace;
+
+    int constexpr invalid = -1;
+    auto format = static_cast<PixelFormat>(invalid);
+    auto dataspace = static_cast<Dataspace>(invalid);
+    auto componentMask = static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(invalid);
+    auto error = mComposerClient->getDisplayedContentSamplingAttributes(mPrimaryDisplay, format,
+                                                                        dataspace, componentMask);
+
+    if (error == Error::UNSUPPORTED) {
+        SUCCEED() << "Device does not support optional extension. Test skipped";
+        return;
+    }
+
+    EXPECT_EQ(error, Error::NONE);
+    EXPECT_NE(format, static_cast<PixelFormat>(invalid));
+    EXPECT_NE(dataspace, static_cast<Dataspace>(invalid));
+    EXPECT_NE(componentMask,
+              static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(invalid));
+};
+
+TEST_F(GraphicsComposerHidlTest, SetDisplayedContentSamplingEnabled) {
+    auto const maxFrames = 10;
+    auto const enableAllComponents = 0;
+    auto error = mComposerClient->setDisplayedContentSamplingEnabled(
+        mPrimaryDisplay, IComposerClient::DisplayedContentSampling::ENABLE, enableAllComponents,
+        maxFrames);
+    if (error == Error::UNSUPPORTED) {
+        SUCCEED() << "Device does not support optional extension. Test skipped";
+        return;
+    }
+    EXPECT_EQ(error, Error::NONE);
+
+    error = mComposerClient->setDisplayedContentSamplingEnabled(
+        mPrimaryDisplay, IComposerClient::DisplayedContentSampling::DISABLE, enableAllComponents,
+        maxFrames);
+    EXPECT_EQ(error, Error::NONE);
+}
+
+TEST_F(GraphicsComposerHidlTest, GetDisplayedContentSample) {
+    int constexpr invalid = -1;
+    auto format = static_cast<PixelFormat>(invalid);
+    auto dataspace = static_cast<Dataspace>(invalid);
+    auto componentMask = static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(invalid);
+    auto error = mComposerClient->getDisplayedContentSamplingAttributes(mPrimaryDisplay, format,
+                                                                        dataspace, componentMask);
+
+    uint64_t maxFrames = 10;
+    uint64_t timestamp = 0;
+    uint64_t frameCount = 0;
+    hidl_array<hidl_vec<uint64_t>, 4> histogram;
+    error = mComposerClient->getDisplayedContentSample(mPrimaryDisplay, maxFrames, timestamp,
+                                                       frameCount, histogram[0], histogram[1],
+                                                       histogram[2], histogram[3]);
+    if (error == Error::UNSUPPORTED) {
+        SUCCEED() << "Device does not support optional extension. Test skipped";
+        return;
+    }
+
+    EXPECT_EQ(error, Error::NONE);
+    EXPECT_LE(frameCount, maxFrames);
+    for (auto i = 0; i < histogram.size(); i++) {
+        if (componentMask & (1 << i)) {
+            EXPECT_NE(histogram[i].size(), 0);
+        } else {
+            EXPECT_EQ(histogram[i].size(), 0);
+        }
+    }
+}
+
 }  // namespace
 }  // namespace vts
 }  // namespace V2_3
diff --git a/media/bufferpool/2.0/IAccessor.hal b/media/bufferpool/2.0/IAccessor.hal
index 66707fe..b889518 100644
--- a/media/bufferpool/2.0/IAccessor.hal
+++ b/media/bufferpool/2.0/IAccessor.hal
@@ -67,6 +67,7 @@
      *     to get shared buffers from the buffer pool.
      * @return connectionId Id of IConnection. The Id identifies
      *     sender and receiver in FMQ messages during buffer transfer.
+     * @return msgId Id of the most recent message from buffer pool.
      * @return toFmqDesc FMQ descriptor. The descriptor is used to
      *     post buffer status messages.
      * @return fromFmqDesc FMQ descriptor. The descriptor is used to
@@ -75,6 +76,7 @@
     connect(IObserver observer)
         generates (ResultStatus status, IConnection connection,
                    int64_t connectionId,
+                   uint32_t msgId,
                    fmq_sync<BufferStatusMessage> toFmqDesc,
                    fmq_unsync<BufferInvalidationMessage> fromFmqDesc);
 };
diff --git a/media/bufferpool/2.0/IObserver.hal b/media/bufferpool/2.0/IObserver.hal
index a998836..62f247e 100644
--- a/media/bufferpool/2.0/IObserver.hal
+++ b/media/bufferpool/2.0/IObserver.hal
@@ -29,6 +29,7 @@
      * message.
      *
      * @param connectionId the connection Id of the specific buffer pool client
+     * @param msgId Id of the most recent message
      */
-    oneway onMessage(int64_t connectionId);
+    oneway onMessage(int64_t connectionId, uint32_t msgId);
 };
diff --git a/media/c2/1.0/Android.bp b/media/c2/1.0/Android.bp
index c37c22b..3c99b6a 100644
--- a/media/c2/1.0/Android.bp
+++ b/media/c2/1.0/Android.bp
@@ -17,8 +17,10 @@
         "IInputSurfaceConnection.hal",
     ],
     interfaces: [
-        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.graphics.bufferqueue@2.0",
         "android.hardware.graphics.common@1.0",
+        "android.hardware.graphics.common@1.1",
+        "android.hardware.graphics.common@1.2",
         "android.hardware.media.bufferpool@2.0",
         "android.hardware.media.omx@1.0",
         "android.hardware.media@1.0",
diff --git a/media/c2/1.0/IComponent.hal b/media/c2/1.0/IComponent.hal
index 7fd551f..822b24e 100644
--- a/media/c2/1.0/IComponent.hal
+++ b/media/c2/1.0/IComponent.hal
@@ -16,7 +16,7 @@
 
 package android.hardware.media.c2@1.0;
 
-import android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer;
+import android.hardware.graphics.bufferqueue@2.0::IGraphicBufferProducer;
 import android.hardware.media.omx@1.0::IGraphicBufferSource;
 
 import IConfigurable;
diff --git a/media/c2/1.0/IInputSurface.hal b/media/c2/1.0/IInputSurface.hal
index 25c6c8e..0a1b56d 100644
--- a/media/c2/1.0/IInputSurface.hal
+++ b/media/c2/1.0/IInputSurface.hal
@@ -16,7 +16,7 @@
 
 package android.hardware.media.c2@1.0;
 
-import android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer;
+import android.hardware.graphics.bufferqueue@2.0::IGraphicBufferProducer;
 
 import IConfigurable;
 
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 18f35c1..1b5e338 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -28,6 +28,7 @@
         "android.hardware.neuralnetworks@1.2",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "libgmock",
         "libhidlmemory",
         "libneuralnetworks_utils",
     ],
@@ -38,23 +39,21 @@
     ],
 }
 
-cc_test {
-    name: "VtsHalNeuralnetworksV1_0TargetTest",
+cc_defaults {
+    name: "VtsHalNeuralNetworksTargetTestDefaults",
+    defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
-        "BasicTests.cpp",
-        "GeneratedTests.cpp",
         "ValidateModel.cpp",
         "ValidateRequest.cpp",
-        "ValidationTests.cpp",
         "VtsHalNeuralnetworks.cpp",
     ],
-    defaults: ["VtsHalTargetTestDefaults"],
     static_libs: [
         "android.hardware.neuralnetworks@1.0",
         "android.hardware.neuralnetworks@1.1",
         "android.hardware.neuralnetworks@1.2",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "libgmock",
         "libhidlmemory",
         "libneuralnetworks_utils",
         "VtsHalNeuralnetworksTest_utils",
@@ -64,4 +63,23 @@
         "libneuralnetworks_generated_test_harness_headers",
         "libneuralnetworks_generated_tests",
     ],
+    // Bug: http://b/74200014 - Disable arm32 asan since it triggers internal
+    // error in ld.gold.
+    arch: {
+        arm: {
+            sanitize: {
+                never: true,
+            },
+        },
+    },
+}
+
+cc_test {
+    name: "VtsHalNeuralnetworksV1_0TargetTest",
+    defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+    srcs: [
+        "BasicTests.cpp",
+        "GeneratedTests.cpp",
+        "ValidationTests.cpp",
+    ],
 }
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index b8046c7..1f66c43 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -36,16 +36,17 @@
 namespace generated_tests {
 using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
 using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using ::test_helper::compare;
+using ::test_helper::expectMultinomialDistributionWithinTolerance;
 using ::test_helper::filter;
+using ::test_helper::Float32Operands;
 using ::test_helper::for_all;
 using ::test_helper::for_each;
-using ::test_helper::resize_accordingly;
-using ::test_helper::MixedTyped;
-using ::test_helper::MixedTypedExampleType;
-using ::test_helper::Float32Operands;
 using ::test_helper::Int32Operands;
+using ::test_helper::MixedTyped;
+using ::test_helper::MixedTypedExample;
 using ::test_helper::Quant8Operands;
-using ::test_helper::compare;
+using ::test_helper::resize_accordingly;
 
 template <typename T>
 void copy_back_(MixedTyped* dst, const std::vector<RequestArgument>& ra, char* src) {
@@ -61,12 +62,15 @@
     copy_back_<float>(dst, ra, src);
     copy_back_<int32_t>(dst, ra, src);
     copy_back_<uint8_t>(dst, ra, src);
+    copy_back_<int16_t>(dst, ra, src);
+    static_assert(4 == std::tuple_size<MixedTyped>::value,
+                  "Number of types in MixedTyped changed, but copy_back function wasn't updated");
 }
 
 // Top level driver for models and examples generated by test_generator.py
 // Test driver for those generated from ml/nn/runtime/test/spec
 void EvaluatePreparedModel(sp<IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
-                           const std::vector<MixedTypedExampleType>& examples, float fpAtol = 1e-5f,
+                           const std::vector<MixedTypedExample>& examples, float fpAtol = 1e-5f,
                            float fpRtol = 1e-5f) {
     const uint32_t INPUT = 0;
     const uint32_t OUTPUT = 1;
@@ -75,8 +79,8 @@
     for (auto& example : examples) {
         SCOPED_TRACE(example_no++);
 
-        const MixedTyped& inputs = example.first;
-        const MixedTyped& golden = example.second;
+        const MixedTyped& inputs = example.operands.first;
+        const MixedTyped& golden = example.operands.second;
 
         std::vector<RequestArgument> inputs_info, outputs_info;
         uint32_t inputSize = 0, outputSize = 0;
@@ -176,12 +180,15 @@
 
         // We want "close-enough" results for float
         compare(filtered_golden, filtered_test, fpAtol, fpRtol);
+
+        if (example.expectedMultinomialDistributionTolerance > 0) {
+            expectMultinomialDistributionWithinTolerance(test, example);
+        }
     }
 }
 
 void Execute(const sp<V1_0::IDevice>& device, std::function<V1_0::Model(void)> create_model,
-             std::function<bool(int)> is_ignored,
-             const std::vector<MixedTypedExampleType>& examples) {
+             std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples) {
     V1_0::Model model = create_model();
 
     // see if service can handle model
@@ -225,8 +232,7 @@
 }
 
 void Execute(const sp<V1_1::IDevice>& device, std::function<V1_1::Model(void)> create_model,
-             std::function<bool(int)> is_ignored,
-             const std::vector<MixedTypedExampleType>& examples) {
+             std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples) {
     V1_1::Model model = create_model();
 
     // see if service can handle model
@@ -277,8 +283,7 @@
 
 // TODO: Reduce code duplication.
 void Execute(const sp<V1_2::IDevice>& device, std::function<V1_2::Model(void)> create_model,
-             std::function<bool(int)> is_ignored,
-             const std::vector<MixedTypedExampleType>& examples) {
+             std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples) {
     V1_2::Model model = create_model();
 
     // see if service can handle model
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTests.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTests.cpp
index d84479c..ac1ae60 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTests.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTests.cpp
@@ -31,9 +31,9 @@
 namespace neuralnetworks {
 
 namespace generated_tests {
-using ::test_helper::MixedTypedExampleType;
+using ::test_helper::MixedTypedExample;
 extern void Execute(const sp<V1_0::IDevice>&, std::function<V1_0::Model(void)>,
-                    std::function<bool(int)>, const std::vector<MixedTypedExampleType>&);
+                    std::function<bool(int)>, const std::vector<MixedTypedExample>&);
 }  // namespace generated_tests
 
 namespace V1_0 {
@@ -43,9 +43,7 @@
 using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
 using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
 using ::android::nn::allocateSharedMemory;
-
-// Mixed-typed examples
-typedef test_helper::MixedTypedExampleType MixedTypedExample;
+using ::test_helper::MixedTypedExample;
 
 // in frameworks/ml/nn/runtime/tests/generated/
 #include "all_generated_V1_0_vts_tests.cpp"
diff --git a/neuralnetworks/1.0/vts/functional/Models.h b/neuralnetworks/1.0/vts/functional/Models.h
index 751ab32..268e671 100644
--- a/neuralnetworks/1.0/vts/functional/Models.h
+++ b/neuralnetworks/1.0/vts/functional/Models.h
@@ -30,7 +30,7 @@
 namespace vts {
 namespace functional {
 
-using MixedTypedExample = test_helper::MixedTypedExampleType;
+using MixedTypedExample = test_helper::MixedTypedExample;
 
 #define FOR_EACH_TEST_MODEL(FN)                          \
     FN(add_broadcast_quant8)                             \
diff --git a/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp
index 09c1878..1d3dee3 100644
--- a/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp
@@ -36,9 +36,9 @@
 using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
 using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
 using ::android::hidl::memory::V1_0::IMemory;
-using test_helper::MixedTyped;
-using test_helper::MixedTypedExampleType;
 using test_helper::for_all;
+using test_helper::MixedTyped;
+using test_helper::MixedTypedExample;
 
 ///////////////////////// UTILITY FUNCTIONS /////////////////////////
 
@@ -151,15 +151,15 @@
 
 ///////////////////////////// ENTRY POINT //////////////////////////////////
 
-std::vector<Request> createRequests(const std::vector<MixedTypedExampleType>& examples) {
+std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples) {
     const uint32_t INPUT = 0;
     const uint32_t OUTPUT = 1;
 
     std::vector<Request> requests;
 
-    for (auto& example : examples) {
-        const MixedTyped& inputs = example.first;
-        const MixedTyped& outputs = example.second;
+    for (const MixedTypedExample& example : examples) {
+        const MixedTyped& inputs = example.operands.first;
+        const MixedTyped& outputs = example.operands.second;
 
         std::vector<RequestArgument> inputs_info, outputs_info;
         uint32_t inputSize = 0, outputSize = 0;
diff --git a/neuralnetworks/1.0/vts/functional/ValidationTests.cpp b/neuralnetworks/1.0/vts/functional/ValidationTests.cpp
index 98fc1c5..d3cbcff 100644
--- a/neuralnetworks/1.0/vts/functional/ValidationTests.cpp
+++ b/neuralnetworks/1.0/vts/functional/ValidationTests.cpp
@@ -27,7 +27,7 @@
 namespace functional {
 
 // forward declarations
-std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
+std::vector<Request> createRequests(const std::vector<::test_helper::MixedTypedExample>& examples);
 
 // generate validation tests
 #define VTS_CURRENT_TEST_CASE(TestName)                                           \
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index 52a804a..df1ac67 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -14,39 +14,23 @@
 // limitations under the License.
 //
 
+// Tests for V1_0 models using the V1_1 HAL.
+cc_test {
+    name: "VtsHalNeuralnetworksV1_1CompatV1_0TargetTest",
+    defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+    srcs: [
+        "GeneratedTestsV1_0.cpp",
+        "ValidationTestsV1_0.cpp",
+    ],
+}
+
+// Tests for V1_1 models.
 cc_test {
     name: "VtsHalNeuralnetworksV1_1TargetTest",
+    defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
     srcs: [
         "BasicTests.cpp",
         "GeneratedTests.cpp",
-        "ValidateModel.cpp",
-        "ValidateRequest.cpp",
         "ValidationTests.cpp",
-        "VtsHalNeuralnetworks.cpp",
     ],
-    defaults: ["VtsHalTargetTestDefaults"],
-    static_libs: [
-        "android.hardware.neuralnetworks@1.0",
-        "android.hardware.neuralnetworks@1.1",
-        "android.hardware.neuralnetworks@1.2",
-        "android.hidl.allocator@1.0",
-        "android.hidl.memory@1.0",
-        "libhidlmemory",
-        "libneuralnetworks_utils",
-        "VtsHalNeuralnetworksTest_utils",
-    ],
-    header_libs: [
-        "libneuralnetworks_headers",
-        "libneuralnetworks_generated_test_harness_headers",
-        "libneuralnetworks_generated_tests",
-    ],
-    // Bug: http://b/74200014 - Disable arm32 asan since it triggers internal
-    // error in ld.gold.
-    arch: {
-        arm: {
-            sanitize: {
-                never: true,
-            },
-        },
-    },
 }
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTests.cpp b/neuralnetworks/1.1/vts/functional/GeneratedTests.cpp
index 95c2b1a..d16f181 100644
--- a/neuralnetworks/1.1/vts/functional/GeneratedTests.cpp
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTests.cpp
@@ -31,9 +31,9 @@
 namespace neuralnetworks {
 
 namespace generated_tests {
-using ::test_helper::MixedTypedExampleType;
+using ::test_helper::MixedTypedExample;
 extern void Execute(const sp<V1_1::IDevice>&, std::function<V1_1::Model(void)>,
-                    std::function<bool(int)>, const std::vector<MixedTypedExampleType>&);
+                    std::function<bool(int)>, const std::vector<MixedTypedExample>&);
 }  // namespace generated_tests
 
 namespace V1_1 {
@@ -43,12 +43,9 @@
 using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
 using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
 using ::android::nn::allocateSharedMemory;
-
-// Mixed-typed examples
-typedef generated_tests::MixedTypedExampleType MixedTypedExample;
+using ::test_helper::MixedTypedExample;
 
 // in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_V1_0_vts_tests.cpp"
 #include "all_generated_V1_1_vts_tests.cpp"
 
 }  // namespace functional
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTestsV1_0.cpp b/neuralnetworks/1.1/vts/functional/GeneratedTestsV1_0.cpp
new file mode 100644
index 0000000..e2acd7d
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTestsV1_0.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "VtsHalNeuralnetworks.h"
+
+#include "Callbacks.h"
+#include "TestHarness.h"
+#include "Utils.h"
+
+#include <android-base/logging.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+
+namespace generated_tests {
+using ::test_helper::MixedTypedExample;
+extern void Execute(const sp<V1_1::IDevice>&, std::function<V1_1::Model(void)>,
+                    std::function<bool(int)>, const std::vector<MixedTypedExample>&);
+}  // namespace generated_tests
+
+namespace V1_1 {
+namespace vts {
+namespace functional {
+
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using ::android::nn::allocateSharedMemory;
+using ::test_helper::MixedTypedExample;
+
+// in frameworks/ml/nn/runtime/tests/generated/
+#include "all_generated_V1_0_vts_tests.cpp"
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_1
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/neuralnetworks/1.1/vts/functional/Models.h b/neuralnetworks/1.1/vts/functional/Models.h
index cc0fac1..57da010 100644
--- a/neuralnetworks/1.1/vts/functional/Models.h
+++ b/neuralnetworks/1.1/vts/functional/Models.h
@@ -31,196 +31,89 @@
 namespace vts {
 namespace functional {
 
-using MixedTypedExample = test_helper::MixedTypedExampleType;
+using MixedTypedExample = test_helper::MixedTypedExample;
 
 #define FOR_EACH_TEST_MODEL(FN)                                  \
-    FN(add)                                                      \
-    FN(add_broadcast_quant8)                                     \
-    FN(add_quant8)                                               \
     FN(add_relaxed)                                              \
-    FN(avg_pool_float_1)                                         \
     FN(avg_pool_float_1_relaxed)                                 \
-    FN(avg_pool_float_2)                                         \
     FN(avg_pool_float_2_relaxed)                                 \
-    FN(avg_pool_float_3)                                         \
     FN(avg_pool_float_3_relaxed)                                 \
-    FN(avg_pool_float_4)                                         \
     FN(avg_pool_float_4_relaxed)                                 \
-    FN(avg_pool_float_5)                                         \
     FN(avg_pool_float_5_relaxed)                                 \
-    FN(avg_pool_quant8_1)                                        \
-    FN(avg_pool_quant8_2)                                        \
-    FN(avg_pool_quant8_3)                                        \
-    FN(avg_pool_quant8_4)                                        \
-    FN(avg_pool_quant8_5)                                        \
     FN(batch_to_space)                                           \
     FN(batch_to_space_float_1)                                   \
     FN(batch_to_space_float_1_relaxed)                           \
     FN(batch_to_space_quant8_1)                                  \
     FN(batch_to_space_relaxed)                                   \
-    FN(concat_float_1)                                           \
     FN(concat_float_1_relaxed)                                   \
-    FN(concat_float_2)                                           \
     FN(concat_float_2_relaxed)                                   \
-    FN(concat_float_3)                                           \
     FN(concat_float_3_relaxed)                                   \
-    FN(concat_quant8_1)                                          \
-    FN(concat_quant8_2)                                          \
-    FN(concat_quant8_3)                                          \
-    FN(conv_1_h3_w2_SAME)                                        \
     FN(conv_1_h3_w2_SAME_relaxed)                                \
-    FN(conv_1_h3_w2_VALID)                                       \
     FN(conv_1_h3_w2_VALID_relaxed)                               \
-    FN(conv_3_h3_w2_SAME)                                        \
     FN(conv_3_h3_w2_SAME_relaxed)                                \
-    FN(conv_3_h3_w2_VALID)                                       \
     FN(conv_3_h3_w2_VALID_relaxed)                               \
-    FN(conv_float)                                               \
-    FN(conv_float_2)                                             \
     FN(conv_float_2_relaxed)                                     \
-    FN(conv_float_channels)                                      \
     FN(conv_float_channels_relaxed)                              \
-    FN(conv_float_channels_weights_as_inputs)                    \
     FN(conv_float_channels_weights_as_inputs_relaxed)            \
-    FN(conv_float_large)                                         \
     FN(conv_float_large_relaxed)                                 \
-    FN(conv_float_large_weights_as_inputs)                       \
     FN(conv_float_large_weights_as_inputs_relaxed)               \
     FN(conv_float_relaxed)                                       \
-    FN(conv_float_weights_as_inputs)                             \
     FN(conv_float_weights_as_inputs_relaxed)                     \
-    FN(conv_quant8)                                              \
-    FN(conv_quant8_2)                                            \
-    FN(conv_quant8_channels)                                     \
-    FN(conv_quant8_channels_weights_as_inputs)                   \
-    FN(conv_quant8_large)                                        \
-    FN(conv_quant8_large_weights_as_inputs)                      \
-    FN(conv_quant8_overflow)                                     \
-    FN(conv_quant8_overflow_weights_as_inputs)                   \
-    FN(conv_quant8_weights_as_inputs)                            \
-    FN(depth_to_space_float_1)                                   \
     FN(depth_to_space_float_1_relaxed)                           \
-    FN(depth_to_space_float_2)                                   \
     FN(depth_to_space_float_2_relaxed)                           \
-    FN(depth_to_space_float_3)                                   \
     FN(depth_to_space_float_3_relaxed)                           \
-    FN(depth_to_space_quant8_1)                                  \
-    FN(depth_to_space_quant8_2)                                  \
-    FN(depthwise_conv)                                           \
-    FN(depthwise_conv2d_float)                                   \
-    FN(depthwise_conv2d_float_2)                                 \
     FN(depthwise_conv2d_float_2_relaxed)                         \
-    FN(depthwise_conv2d_float_large)                             \
-    FN(depthwise_conv2d_float_large_2)                           \
     FN(depthwise_conv2d_float_large_2_relaxed)                   \
-    FN(depthwise_conv2d_float_large_2_weights_as_inputs)         \
     FN(depthwise_conv2d_float_large_2_weights_as_inputs_relaxed) \
     FN(depthwise_conv2d_float_large_relaxed)                     \
-    FN(depthwise_conv2d_float_large_weights_as_inputs)           \
     FN(depthwise_conv2d_float_large_weights_as_inputs_relaxed)   \
     FN(depthwise_conv2d_float_relaxed)                           \
-    FN(depthwise_conv2d_float_weights_as_inputs)                 \
     FN(depthwise_conv2d_float_weights_as_inputs_relaxed)         \
-    FN(depthwise_conv2d_quant8)                                  \
-    FN(depthwise_conv2d_quant8_2)                                \
-    FN(depthwise_conv2d_quant8_large)                            \
-    FN(depthwise_conv2d_quant8_large_weights_as_inputs)          \
-    FN(depthwise_conv2d_quant8_weights_as_inputs)                \
     FN(depthwise_conv_relaxed)                                   \
-    FN(dequantize)                                               \
     FN(dequantize_relaxed)                                       \
     FN(div)                                                      \
     FN(div_broadcast_float)                                      \
     FN(div_broadcast_float_relaxed)                              \
     FN(div_relaxed)                                              \
-    FN(embedding_lookup)                                         \
     FN(embedding_lookup_relaxed)                                 \
-    FN(floor)                                                    \
     FN(floor_relaxed)                                            \
-    FN(fully_connected_float)                                    \
-    FN(fully_connected_float_2)                                  \
     FN(fully_connected_float_2_relaxed)                          \
     FN(fully_connected_float_4d_simple)                          \
     FN(fully_connected_float_4d_simple_relaxed)                  \
-    FN(fully_connected_float_large)                              \
     FN(fully_connected_float_large_relaxed)                      \
-    FN(fully_connected_float_large_weights_as_inputs)            \
     FN(fully_connected_float_large_weights_as_inputs_relaxed)    \
     FN(fully_connected_float_relaxed)                            \
-    FN(fully_connected_float_weights_as_inputs)                  \
     FN(fully_connected_float_weights_as_inputs_relaxed)          \
-    FN(fully_connected_quant8)                                   \
-    FN(fully_connected_quant8_2)                                 \
-    FN(fully_connected_quant8_large)                             \
-    FN(fully_connected_quant8_large_weights_as_inputs)           \
-    FN(fully_connected_quant8_weights_as_inputs)                 \
-    FN(hashtable_lookup_float)                                   \
     FN(hashtable_lookup_float_relaxed)                           \
-    FN(hashtable_lookup_quant8)                                  \
-    FN(l2_normalization)                                         \
-    FN(l2_normalization_2)                                       \
     FN(l2_normalization_2_relaxed)                               \
-    FN(l2_normalization_large)                                   \
     FN(l2_normalization_large_relaxed)                           \
     FN(l2_normalization_relaxed)                                 \
-    FN(l2_pool_float)                                            \
-    FN(l2_pool_float_2)                                          \
     FN(l2_pool_float_2_relaxed)                                  \
-    FN(l2_pool_float_large)                                      \
     FN(l2_pool_float_large_relaxed)                              \
     FN(l2_pool_float_relaxed)                                    \
-    FN(local_response_norm_float_1)                              \
     FN(local_response_norm_float_1_relaxed)                      \
-    FN(local_response_norm_float_2)                              \
     FN(local_response_norm_float_2_relaxed)                      \
-    FN(local_response_norm_float_3)                              \
     FN(local_response_norm_float_3_relaxed)                      \
-    FN(local_response_norm_float_4)                              \
     FN(local_response_norm_float_4_relaxed)                      \
-    FN(logistic_float_1)                                         \
     FN(logistic_float_1_relaxed)                                 \
-    FN(logistic_float_2)                                         \
     FN(logistic_float_2_relaxed)                                 \
-    FN(logistic_quant8_1)                                        \
-    FN(logistic_quant8_2)                                        \
-    FN(lsh_projection)                                           \
-    FN(lsh_projection_2)                                         \
     FN(lsh_projection_2_relaxed)                                 \
     FN(lsh_projection_relaxed)                                   \
-    FN(lsh_projection_weights_as_inputs)                         \
     FN(lsh_projection_weights_as_inputs_relaxed)                 \
-    FN(lstm)                                                     \
-    FN(lstm2)                                                    \
     FN(lstm2_relaxed)                                            \
-    FN(lstm2_state)                                              \
-    FN(lstm2_state2)                                             \
     FN(lstm2_state2_relaxed)                                     \
     FN(lstm2_state_relaxed)                                      \
-    FN(lstm3)                                                    \
     FN(lstm3_relaxed)                                            \
-    FN(lstm3_state)                                              \
-    FN(lstm3_state2)                                             \
     FN(lstm3_state2_relaxed)                                     \
-    FN(lstm3_state3)                                             \
     FN(lstm3_state3_relaxed)                                     \
     FN(lstm3_state_relaxed)                                      \
     FN(lstm_relaxed)                                             \
-    FN(lstm_state)                                               \
-    FN(lstm_state2)                                              \
     FN(lstm_state2_relaxed)                                      \
     FN(lstm_state_relaxed)                                       \
-    FN(max_pool_float_1)                                         \
     FN(max_pool_float_1_relaxed)                                 \
-    FN(max_pool_float_2)                                         \
     FN(max_pool_float_2_relaxed)                                 \
-    FN(max_pool_float_3)                                         \
     FN(max_pool_float_3_relaxed)                                 \
-    FN(max_pool_float_4)                                         \
     FN(max_pool_float_4_relaxed)                                 \
-    FN(max_pool_quant8_1)                                        \
-    FN(max_pool_quant8_2)                                        \
-    FN(max_pool_quant8_3)                                        \
-    FN(max_pool_quant8_4)                                        \
     FN(mean)                                                     \
     FN(mean_float_1)                                             \
     FN(mean_float_1_relaxed)                                     \
@@ -229,57 +122,27 @@
     FN(mean_quant8_1)                                            \
     FN(mean_quant8_2)                                            \
     FN(mean_relaxed)                                             \
-    FN(mobilenet_224_gender_basic_fixed)                         \
     FN(mobilenet_224_gender_basic_fixed_relaxed)                 \
-    FN(mobilenet_quantized)                                      \
-    FN(mul)                                                      \
-    FN(mul_broadcast_quant8)                                     \
-    FN(mul_quant8)                                               \
     FN(mul_relaxed)                                              \
-    FN(mul_relu)                                                 \
     FN(mul_relu_relaxed)                                         \
     FN(pad)                                                      \
     FN(pad_float_1)                                              \
     FN(pad_float_1_relaxed)                                      \
     FN(pad_relaxed)                                              \
-    FN(relu1_float_1)                                            \
     FN(relu1_float_1_relaxed)                                    \
-    FN(relu1_float_2)                                            \
     FN(relu1_float_2_relaxed)                                    \
-    FN(relu1_quant8_1)                                           \
-    FN(relu1_quant8_2)                                           \
-    FN(relu6_float_1)                                            \
     FN(relu6_float_1_relaxed)                                    \
-    FN(relu6_float_2)                                            \
     FN(relu6_float_2_relaxed)                                    \
-    FN(relu6_quant8_1)                                           \
-    FN(relu6_quant8_2)                                           \
-    FN(relu_float_1)                                             \
     FN(relu_float_1_relaxed)                                     \
-    FN(relu_float_2)                                             \
     FN(relu_float_2_relaxed)                                     \
-    FN(relu_quant8_1)                                            \
-    FN(relu_quant8_2)                                            \
-    FN(reshape)                                                  \
-    FN(reshape_quant8)                                           \
-    FN(reshape_quant8_weights_as_inputs)                         \
     FN(reshape_relaxed)                                          \
-    FN(reshape_weights_as_inputs)                                \
     FN(reshape_weights_as_inputs_relaxed)                        \
-    FN(resize_bilinear)                                          \
-    FN(resize_bilinear_2)                                        \
     FN(resize_bilinear_2_relaxed)                                \
     FN(resize_bilinear_relaxed)                                  \
-    FN(rnn)                                                      \
     FN(rnn_relaxed)                                              \
-    FN(rnn_state)                                                \
     FN(rnn_state_relaxed)                                        \
-    FN(softmax_float_1)                                          \
     FN(softmax_float_1_relaxed)                                  \
-    FN(softmax_float_2)                                          \
     FN(softmax_float_2_relaxed)                                  \
-    FN(softmax_quant8_1)                                         \
-    FN(softmax_quant8_2)                                         \
     FN(space_to_batch)                                           \
     FN(space_to_batch_float_1)                                   \
     FN(space_to_batch_float_1_relaxed)                           \
@@ -291,14 +154,9 @@
     FN(space_to_batch_quant8_2)                                  \
     FN(space_to_batch_quant8_3)                                  \
     FN(space_to_batch_relaxed)                                   \
-    FN(space_to_depth_float_1)                                   \
     FN(space_to_depth_float_1_relaxed)                           \
-    FN(space_to_depth_float_2)                                   \
     FN(space_to_depth_float_2_relaxed)                           \
-    FN(space_to_depth_float_3)                                   \
     FN(space_to_depth_float_3_relaxed)                           \
-    FN(space_to_depth_quant8_1)                                  \
-    FN(space_to_depth_quant8_2)                                  \
     FN(squeeze)                                                  \
     FN(squeeze_float_1)                                          \
     FN(squeeze_float_1_relaxed)                                  \
@@ -343,13 +201,9 @@
     FN(sub_broadcast_float)                                      \
     FN(sub_broadcast_float_relaxed)                              \
     FN(sub_relaxed)                                              \
-    FN(svdf)                                                     \
-    FN(svdf2)                                                    \
     FN(svdf2_relaxed)                                            \
     FN(svdf_relaxed)                                             \
-    FN(svdf_state)                                               \
     FN(svdf_state_relaxed)                                       \
-    FN(tanh)                                                     \
     FN(tanh_relaxed)                                             \
     FN(transpose)                                                \
     FN(transpose_float_1)                                        \
diff --git a/neuralnetworks/1.1/vts/functional/ModelsV1_0.h b/neuralnetworks/1.1/vts/functional/ModelsV1_0.h
new file mode 100644
index 0000000..52c0346
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/ModelsV1_0.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VTS_HAL_NEURALNETWORKS_V1_1_VTS_FUNCTIONAL_MODELS_V1_0_H
+#define VTS_HAL_NEURALNETWORKS_V1_1_VTS_FUNCTIONAL_MODELS_V1_0_H
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "TestHarness.h"
+
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_1 {
+namespace vts {
+namespace functional {
+
+using MixedTypedExample = test_helper::MixedTypedExample;
+
+#define FOR_EACH_TEST_MODEL(FN)                          \
+    FN(add_broadcast_quant8)                             \
+    FN(add)                                              \
+    FN(add_quant8)                                       \
+    FN(avg_pool_float_1)                                 \
+    FN(avg_pool_float_2)                                 \
+    FN(avg_pool_float_3)                                 \
+    FN(avg_pool_float_4)                                 \
+    FN(avg_pool_float_5)                                 \
+    FN(avg_pool_quant8_1)                                \
+    FN(avg_pool_quant8_2)                                \
+    FN(avg_pool_quant8_3)                                \
+    FN(avg_pool_quant8_4)                                \
+    FN(avg_pool_quant8_5)                                \
+    FN(concat_float_1)                                   \
+    FN(concat_float_2)                                   \
+    FN(concat_float_3)                                   \
+    FN(concat_quant8_1)                                  \
+    FN(concat_quant8_2)                                  \
+    FN(concat_quant8_3)                                  \
+    FN(conv_1_h3_w2_SAME)                                \
+    FN(conv_1_h3_w2_VALID)                               \
+    FN(conv_3_h3_w2_SAME)                                \
+    FN(conv_3_h3_w2_VALID)                               \
+    FN(conv_float_2)                                     \
+    FN(conv_float_channels)                              \
+    FN(conv_float_channels_weights_as_inputs)            \
+    FN(conv_float_large)                                 \
+    FN(conv_float_large_weights_as_inputs)               \
+    FN(conv_float)                                       \
+    FN(conv_float_weights_as_inputs)                     \
+    FN(conv_quant8_2)                                    \
+    FN(conv_quant8_channels)                             \
+    FN(conv_quant8_channels_weights_as_inputs)           \
+    FN(conv_quant8_large)                                \
+    FN(conv_quant8_large_weights_as_inputs)              \
+    FN(conv_quant8)                                      \
+    FN(conv_quant8_overflow)                             \
+    FN(conv_quant8_overflow_weights_as_inputs)           \
+    FN(conv_quant8_weights_as_inputs)                    \
+    FN(depth_to_space_float_1)                           \
+    FN(depth_to_space_float_2)                           \
+    FN(depth_to_space_float_3)                           \
+    FN(depth_to_space_quant8_1)                          \
+    FN(depth_to_space_quant8_2)                          \
+    FN(depthwise_conv2d_float_2)                         \
+    FN(depthwise_conv2d_float_large_2)                   \
+    FN(depthwise_conv2d_float_large_2_weights_as_inputs) \
+    FN(depthwise_conv2d_float_large)                     \
+    FN(depthwise_conv2d_float_large_weights_as_inputs)   \
+    FN(depthwise_conv2d_float)                           \
+    FN(depthwise_conv2d_float_weights_as_inputs)         \
+    FN(depthwise_conv2d_quant8_2)                        \
+    FN(depthwise_conv2d_quant8_large)                    \
+    FN(depthwise_conv2d_quant8_large_weights_as_inputs)  \
+    FN(depthwise_conv2d_quant8)                          \
+    FN(depthwise_conv2d_quant8_weights_as_inputs)        \
+    FN(depthwise_conv)                                   \
+    FN(dequantize)                                       \
+    FN(embedding_lookup)                                 \
+    FN(floor)                                            \
+    FN(fully_connected_float_2)                          \
+    FN(fully_connected_float_large)                      \
+    FN(fully_connected_float_large_weights_as_inputs)    \
+    FN(fully_connected_float)                            \
+    FN(fully_connected_float_weights_as_inputs)          \
+    FN(fully_connected_quant8_2)                         \
+    FN(fully_connected_quant8_large)                     \
+    FN(fully_connected_quant8_large_weights_as_inputs)   \
+    FN(fully_connected_quant8)                           \
+    FN(fully_connected_quant8_weights_as_inputs)         \
+    FN(hashtable_lookup_float)                           \
+    FN(hashtable_lookup_quant8)                          \
+    FN(l2_normalization_2)                               \
+    FN(l2_normalization_large)                           \
+    FN(l2_normalization)                                 \
+    FN(l2_pool_float_2)                                  \
+    FN(l2_pool_float_large)                              \
+    FN(l2_pool_float)                                    \
+    FN(local_response_norm_float_1)                      \
+    FN(local_response_norm_float_2)                      \
+    FN(local_response_norm_float_3)                      \
+    FN(local_response_norm_float_4)                      \
+    FN(logistic_float_1)                                 \
+    FN(logistic_float_2)                                 \
+    FN(logistic_quant8_1)                                \
+    FN(logistic_quant8_2)                                \
+    FN(lsh_projection_2)                                 \
+    FN(lsh_projection)                                   \
+    FN(lsh_projection_weights_as_inputs)                 \
+    FN(lstm2)                                            \
+    FN(lstm2_state2)                                     \
+    FN(lstm2_state)                                      \
+    FN(lstm3)                                            \
+    FN(lstm3_state2)                                     \
+    FN(lstm3_state3)                                     \
+    FN(lstm3_state)                                      \
+    FN(lstm)                                             \
+    FN(lstm_state2)                                      \
+    FN(lstm_state)                                       \
+    FN(max_pool_float_1)                                 \
+    FN(max_pool_float_2)                                 \
+    FN(max_pool_float_3)                                 \
+    FN(max_pool_float_4)                                 \
+    FN(max_pool_quant8_1)                                \
+    FN(max_pool_quant8_2)                                \
+    FN(max_pool_quant8_3)                                \
+    FN(max_pool_quant8_4)                                \
+    FN(mobilenet_224_gender_basic_fixed)                 \
+    FN(mobilenet_quantized)                              \
+    FN(mul_broadcast_quant8)                             \
+    FN(mul)                                              \
+    FN(mul_quant8)                                       \
+    FN(mul_relu)                                         \
+    FN(relu1_float_1)                                    \
+    FN(relu1_float_2)                                    \
+    FN(relu1_quant8_1)                                   \
+    FN(relu1_quant8_2)                                   \
+    FN(relu6_float_1)                                    \
+    FN(relu6_float_2)                                    \
+    FN(relu6_quant8_1)                                   \
+    FN(relu6_quant8_2)                                   \
+    FN(relu_float_1)                                     \
+    FN(relu_float_2)                                     \
+    FN(relu_quant8_1)                                    \
+    FN(relu_quant8_2)                                    \
+    FN(reshape)                                          \
+    FN(reshape_quant8)                                   \
+    FN(reshape_quant8_weights_as_inputs)                 \
+    FN(reshape_weights_as_inputs)                        \
+    FN(resize_bilinear_2)                                \
+    FN(resize_bilinear)                                  \
+    FN(rnn)                                              \
+    FN(rnn_state)                                        \
+    FN(softmax_float_1)                                  \
+    FN(softmax_float_2)                                  \
+    FN(softmax_quant8_1)                                 \
+    FN(softmax_quant8_2)                                 \
+    FN(space_to_depth_float_1)                           \
+    FN(space_to_depth_float_2)                           \
+    FN(space_to_depth_float_3)                           \
+    FN(space_to_depth_quant8_1)                          \
+    FN(space_to_depth_quant8_2)                          \
+    FN(svdf2)                                            \
+    FN(svdf)                                             \
+    FN(svdf_state)                                       \
+    FN(tanh)
+
+#define FORWARD_DECLARE_GENERATED_OBJECTS(function) \
+    namespace function {                            \
+    extern std::vector<MixedTypedExample> examples; \
+    Model createTestModel();                        \
+    }
+
+FOR_EACH_TEST_MODEL(FORWARD_DECLARE_GENERATED_OBJECTS)
+
+#undef FORWARD_DECLARE_GENERATED_OBJECTS
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_1
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+#endif  // VTS_HAL_NEURALNETWORKS_V1_1_VTS_FUNCTIONAL_MODELS_V1_0_H
diff --git a/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp
index 687b760..e7d96c7 100644
--- a/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp
@@ -36,9 +36,9 @@
 using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
 using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
 using ::android::hidl::memory::V1_0::IMemory;
-using test_helper::MixedTyped;
-using test_helper::MixedTypedExampleType;
 using test_helper::for_all;
+using test_helper::MixedTyped;
+using test_helper::MixedTypedExample;
 
 ///////////////////////// UTILITY FUNCTIONS /////////////////////////
 
@@ -152,15 +152,15 @@
 
 ///////////////////////////// ENTRY POINT //////////////////////////////////
 
-std::vector<Request> createRequests(const std::vector<MixedTypedExampleType>& examples) {
+std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples) {
     const uint32_t INPUT = 0;
     const uint32_t OUTPUT = 1;
 
     std::vector<Request> requests;
 
     for (auto& example : examples) {
-        const MixedTyped& inputs = example.first;
-        const MixedTyped& outputs = example.second;
+        const MixedTyped& inputs = example.operands.first;
+        const MixedTyped& outputs = example.operands.second;
 
         std::vector<RequestArgument> inputs_info, outputs_info;
         uint32_t inputSize = 0, outputSize = 0;
diff --git a/neuralnetworks/1.1/vts/functional/ValidationTestsV1_0.cpp b/neuralnetworks/1.1/vts/functional/ValidationTestsV1_0.cpp
new file mode 100644
index 0000000..7e2af05
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/ValidationTestsV1_0.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "ModelsV1_0.h"
+#include "VtsHalNeuralnetworks.h"
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_1 {
+namespace vts {
+namespace functional {
+
+// forward declarations
+std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
+
+// generate validation tests
+#define VTS_CURRENT_TEST_CASE(TestName)                                           \
+    TEST_F(ValidationTest, TestName) {                                            \
+        const Model model = TestName::createTestModel();                          \
+        const std::vector<Request> requests = createRequests(TestName::examples); \
+        validateModel(model);                                                     \
+        validateRequests(model, requests);                                        \
+    }
+
+FOR_EACH_TEST_MODEL(VTS_CURRENT_TEST_CASE)
+
+#undef VTS_CURRENT_TEST_CASE
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_1
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 2dc19cc..087c12f 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -14,39 +14,33 @@
 // limitations under the License.
 //
 
+// Tests for V1_0 models using the V1_2 HAL.
+cc_test {
+    name: "VtsHalNeuralnetworksV1_2CompatV1_0TargetTest",
+    defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+    srcs: [
+        "GeneratedTestsV1_0.cpp",
+        "ValidationTestsV1_0.cpp",
+    ]
+}
+
+// Tests for V1_1 models using the V1_2 HAL.
+cc_test {
+    name: "VtsHalNeuralnetworksV1_2CompatV1_1TargetTest",
+    defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+    srcs: [
+        "GeneratedTestsV1_1.cpp",
+        "ValidationTestsV1_1.cpp",
+    ],
+}
+
+// Tests for V1_2 models.
 cc_test {
     name: "VtsHalNeuralnetworksV1_2TargetTest",
+    defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
     srcs: [
         "BasicTests.cpp",
         "GeneratedTests.cpp",
-        "ValidateModel.cpp",
-        "ValidateRequest.cpp",
         "ValidationTests.cpp",
-        "VtsHalNeuralnetworks.cpp",
     ],
-    defaults: ["VtsHalTargetTestDefaults"],
-    static_libs: [
-        "android.hardware.neuralnetworks@1.0",
-        "android.hardware.neuralnetworks@1.1",
-        "android.hardware.neuralnetworks@1.2",
-        "android.hidl.allocator@1.0",
-        "android.hidl.memory@1.0",
-        "libhidlmemory",
-        "libneuralnetworks_utils",
-        "VtsHalNeuralnetworksTest_utils",
-    ],
-    header_libs: [
-        "libneuralnetworks_headers",
-        "libneuralnetworks_generated_test_harness_headers",
-        "libneuralnetworks_generated_tests",
-    ],
-    // Bug: http://b/74200014 - Disable arm32 asan since it triggers internal
-    // error in ld.gold.
-    arch: {
-        arm: {
-            sanitize: {
-                never: true,
-            },
-        },
-    },
 }
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTests.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTests.cpp
index 662c531..0608139 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTests.cpp
@@ -31,9 +31,9 @@
 namespace neuralnetworks {
 
 namespace generated_tests {
-using ::test_helper::MixedTypedExampleType;
+using ::test_helper::MixedTypedExample;
 extern void Execute(const sp<V1_2::IDevice>&, std::function<V1_2::Model(void)>,
-                    std::function<bool(int)>, const std::vector<MixedTypedExampleType>&);
+                    std::function<bool(int)>, const std::vector<MixedTypedExample>&);
 }  // namespace generated_tests
 
 namespace V1_2 {
@@ -43,13 +43,9 @@
 using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
 using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
 using ::android::nn::allocateSharedMemory;
-
-// Mixed-typed examples
-typedef generated_tests::MixedTypedExampleType MixedTypedExample;
+using ::test_helper::MixedTypedExample;
 
 // in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_V1_0_vts_tests.cpp"
-#include "all_generated_V1_1_vts_tests.cpp"
 #include "all_generated_V1_2_vts_tests.cpp"
 
 }  // namespace functional
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_0.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_0.cpp
new file mode 100644
index 0000000..8d685d1
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_0.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "VtsHalNeuralnetworks.h"
+
+#include "Callbacks.h"
+#include "TestHarness.h"
+#include "Utils.h"
+
+#include <android-base/logging.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+
+namespace generated_tests {
+using ::test_helper::MixedTypedExample;
+extern void Execute(const sp<V1_2::IDevice>&, std::function<V1_2::Model(void)>,
+                    std::function<bool(int)>, const std::vector<MixedTypedExample>&);
+}  // namespace generated_tests
+
+namespace V1_2 {
+namespace vts {
+namespace functional {
+
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using ::android::nn::allocateSharedMemory;
+using ::test_helper::MixedTypedExample;
+
+// in frameworks/ml/nn/runtime/tests/generated/
+#include "all_generated_V1_0_vts_tests.cpp"
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_2
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_1.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_1.cpp
new file mode 100644
index 0000000..8dbb586
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_1.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "VtsHalNeuralnetworks.h"
+
+#include "Callbacks.h"
+#include "TestHarness.h"
+#include "Utils.h"
+
+#include <android-base/logging.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+
+namespace generated_tests {
+using ::test_helper::MixedTypedExample;
+extern void Execute(const sp<V1_2::IDevice>&, std::function<V1_2::Model(void)>,
+                    std::function<bool(int)>, const std::vector<MixedTypedExample>&);
+}  // namespace generated_tests
+
+namespace V1_2 {
+namespace vts {
+namespace functional {
+
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using ::android::nn::allocateSharedMemory;
+using ::test_helper::MixedTypedExample;
+
+// in frameworks/ml/nn/runtime/tests/generated/
+#include "all_generated_V1_1_vts_tests.cpp"
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_2
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/neuralnetworks/1.2/vts/functional/Models.h b/neuralnetworks/1.2/vts/functional/Models.h
index f3769bc..2426ad0 100644
--- a/neuralnetworks/1.2/vts/functional/Models.h
+++ b/neuralnetworks/1.2/vts/functional/Models.h
@@ -32,331 +32,9 @@
 namespace vts {
 namespace functional {
 
-using MixedTypedExample = test_helper::MixedTypedExampleType;
+using MixedTypedExample = test_helper::MixedTypedExample;
 
-#define FOR_EACH_TEST_MODEL(FN)                                  \
-    FN(add)                                                      \
-    FN(add_broadcast_quant8)                                     \
-    FN(add_quant8)                                               \
-    FN(add_relaxed)                                              \
-    FN(avg_pool_float_1)                                         \
-    FN(avg_pool_float_1_relaxed)                                 \
-    FN(avg_pool_float_2)                                         \
-    FN(avg_pool_float_2_relaxed)                                 \
-    FN(avg_pool_float_3)                                         \
-    FN(avg_pool_float_3_relaxed)                                 \
-    FN(avg_pool_float_4)                                         \
-    FN(avg_pool_float_4_relaxed)                                 \
-    FN(avg_pool_float_5)                                         \
-    FN(avg_pool_float_5_relaxed)                                 \
-    FN(avg_pool_quant8_1)                                        \
-    FN(avg_pool_quant8_2)                                        \
-    FN(avg_pool_quant8_3)                                        \
-    FN(avg_pool_quant8_4)                                        \
-    FN(avg_pool_quant8_5)                                        \
-    FN(batch_to_space)                                           \
-    FN(batch_to_space_float_1)                                   \
-    FN(batch_to_space_float_1_relaxed)                           \
-    FN(batch_to_space_quant8_1)                                  \
-    FN(batch_to_space_relaxed)                                   \
-    FN(concat_float_1)                                           \
-    FN(concat_float_1_relaxed)                                   \
-    FN(concat_float_2)                                           \
-    FN(concat_float_2_relaxed)                                   \
-    FN(concat_float_3)                                           \
-    FN(concat_float_3_relaxed)                                   \
-    FN(concat_quant8_1)                                          \
-    FN(concat_quant8_2)                                          \
-    FN(concat_quant8_3)                                          \
-    FN(conv_1_h3_w2_SAME)                                        \
-    FN(conv_1_h3_w2_SAME_relaxed)                                \
-    FN(conv_1_h3_w2_VALID)                                       \
-    FN(conv_1_h3_w2_VALID_relaxed)                               \
-    FN(conv_3_h3_w2_SAME)                                        \
-    FN(conv_3_h3_w2_SAME_relaxed)                                \
-    FN(conv_3_h3_w2_VALID)                                       \
-    FN(conv_3_h3_w2_VALID_relaxed)                               \
-    FN(conv_float)                                               \
-    FN(conv_float_2)                                             \
-    FN(conv_float_2_relaxed)                                     \
-    FN(conv_float_channels)                                      \
-    FN(conv_float_channels_relaxed)                              \
-    FN(conv_float_channels_weights_as_inputs)                    \
-    FN(conv_float_channels_weights_as_inputs_relaxed)            \
-    FN(conv_float_large)                                         \
-    FN(conv_float_large_relaxed)                                 \
-    FN(conv_float_large_weights_as_inputs)                       \
-    FN(conv_float_large_weights_as_inputs_relaxed)               \
-    FN(conv_float_relaxed)                                       \
-    FN(conv_float_weights_as_inputs)                             \
-    FN(conv_float_weights_as_inputs_relaxed)                     \
-    FN(conv_quant8)                                              \
-    FN(conv_quant8_2)                                            \
-    FN(conv_quant8_channels)                                     \
-    FN(conv_quant8_channels_weights_as_inputs)                   \
-    FN(conv_quant8_large)                                        \
-    FN(conv_quant8_large_weights_as_inputs)                      \
-    FN(conv_quant8_overflow)                                     \
-    FN(conv_quant8_overflow_weights_as_inputs)                   \
-    FN(conv_quant8_weights_as_inputs)                            \
-    FN(depth_to_space_float_1)                                   \
-    FN(depth_to_space_float_1_relaxed)                           \
-    FN(depth_to_space_float_2)                                   \
-    FN(depth_to_space_float_2_relaxed)                           \
-    FN(depth_to_space_float_3)                                   \
-    FN(depth_to_space_float_3_relaxed)                           \
-    FN(depth_to_space_quant8_1)                                  \
-    FN(depth_to_space_quant8_2)                                  \
-    FN(depthwise_conv)                                           \
-    FN(depthwise_conv2d_float)                                   \
-    FN(depthwise_conv2d_float_2)                                 \
-    FN(depthwise_conv2d_float_2_relaxed)                         \
-    FN(depthwise_conv2d_float_large)                             \
-    FN(depthwise_conv2d_float_large_2)                           \
-    FN(depthwise_conv2d_float_large_2_relaxed)                   \
-    FN(depthwise_conv2d_float_large_2_weights_as_inputs)         \
-    FN(depthwise_conv2d_float_large_2_weights_as_inputs_relaxed) \
-    FN(depthwise_conv2d_float_large_relaxed)                     \
-    FN(depthwise_conv2d_float_large_weights_as_inputs)           \
-    FN(depthwise_conv2d_float_large_weights_as_inputs_relaxed)   \
-    FN(depthwise_conv2d_float_relaxed)                           \
-    FN(depthwise_conv2d_float_weights_as_inputs)                 \
-    FN(depthwise_conv2d_float_weights_as_inputs_relaxed)         \
-    FN(depthwise_conv2d_quant8)                                  \
-    FN(depthwise_conv2d_quant8_2)                                \
-    FN(depthwise_conv2d_quant8_large)                            \
-    FN(depthwise_conv2d_quant8_large_weights_as_inputs)          \
-    FN(depthwise_conv2d_quant8_weights_as_inputs)                \
-    FN(depthwise_conv_relaxed)                                   \
-    FN(dequantize)                                               \
-    FN(dequantize_relaxed)                                       \
-    FN(div)                                                      \
-    FN(div_broadcast_float)                                      \
-    FN(div_broadcast_float_relaxed)                              \
-    FN(div_relaxed)                                              \
-    FN(embedding_lookup)                                         \
-    FN(embedding_lookup_relaxed)                                 \
-    FN(floor)                                                    \
-    FN(floor_relaxed)                                            \
-    FN(fully_connected_float)                                    \
-    FN(fully_connected_float_2)                                  \
-    FN(fully_connected_float_2_relaxed)                          \
-    FN(fully_connected_float_4d_simple)                          \
-    FN(fully_connected_float_4d_simple_relaxed)                  \
-    FN(fully_connected_float_large)                              \
-    FN(fully_connected_float_large_relaxed)                      \
-    FN(fully_connected_float_large_weights_as_inputs)            \
-    FN(fully_connected_float_large_weights_as_inputs_relaxed)    \
-    FN(fully_connected_float_relaxed)                            \
-    FN(fully_connected_float_weights_as_inputs)                  \
-    FN(fully_connected_float_weights_as_inputs_relaxed)          \
-    FN(fully_connected_quant8)                                   \
-    FN(fully_connected_quant8_2)                                 \
-    FN(fully_connected_quant8_large)                             \
-    FN(fully_connected_quant8_large_weights_as_inputs)           \
-    FN(fully_connected_quant8_weights_as_inputs)                 \
-    FN(hashtable_lookup_float)                                   \
-    FN(hashtable_lookup_float_relaxed)                           \
-    FN(hashtable_lookup_quant8)                                  \
-    FN(l2_normalization)                                         \
-    FN(l2_normalization_2)                                       \
-    FN(l2_normalization_2_relaxed)                               \
-    FN(l2_normalization_large)                                   \
-    FN(l2_normalization_large_relaxed)                           \
-    FN(l2_normalization_relaxed)                                 \
-    FN(l2_pool_float)                                            \
-    FN(l2_pool_float_2)                                          \
-    FN(l2_pool_float_2_relaxed)                                  \
-    FN(l2_pool_float_large)                                      \
-    FN(l2_pool_float_large_relaxed)                              \
-    FN(l2_pool_float_relaxed)                                    \
-    FN(local_response_norm_float_1)                              \
-    FN(local_response_norm_float_1_relaxed)                      \
-    FN(local_response_norm_float_2)                              \
-    FN(local_response_norm_float_2_relaxed)                      \
-    FN(local_response_norm_float_3)                              \
-    FN(local_response_norm_float_3_relaxed)                      \
-    FN(local_response_norm_float_4)                              \
-    FN(local_response_norm_float_4_relaxed)                      \
-    FN(logistic_float_1)                                         \
-    FN(logistic_float_1_relaxed)                                 \
-    FN(logistic_float_2)                                         \
-    FN(logistic_float_2_relaxed)                                 \
-    FN(logistic_quant8_1)                                        \
-    FN(logistic_quant8_2)                                        \
-    FN(lsh_projection)                                           \
-    FN(lsh_projection_2)                                         \
-    FN(lsh_projection_2_relaxed)                                 \
-    FN(lsh_projection_relaxed)                                   \
-    FN(lsh_projection_weights_as_inputs)                         \
-    FN(lsh_projection_weights_as_inputs_relaxed)                 \
-    FN(lstm)                                                     \
-    FN(lstm2)                                                    \
-    FN(lstm2_relaxed)                                            \
-    FN(lstm2_state)                                              \
-    FN(lstm2_state2)                                             \
-    FN(lstm2_state2_relaxed)                                     \
-    FN(lstm2_state_relaxed)                                      \
-    FN(lstm3)                                                    \
-    FN(lstm3_relaxed)                                            \
-    FN(lstm3_state)                                              \
-    FN(lstm3_state2)                                             \
-    FN(lstm3_state2_relaxed)                                     \
-    FN(lstm3_state3)                                             \
-    FN(lstm3_state3_relaxed)                                     \
-    FN(lstm3_state_relaxed)                                      \
-    FN(lstm_relaxed)                                             \
-    FN(lstm_state)                                               \
-    FN(lstm_state2)                                              \
-    FN(lstm_state2_relaxed)                                      \
-    FN(lstm_state_relaxed)                                       \
-    FN(max_pool_float_1)                                         \
-    FN(max_pool_float_1_relaxed)                                 \
-    FN(max_pool_float_2)                                         \
-    FN(max_pool_float_2_relaxed)                                 \
-    FN(max_pool_float_3)                                         \
-    FN(max_pool_float_3_relaxed)                                 \
-    FN(max_pool_float_4)                                         \
-    FN(max_pool_float_4_relaxed)                                 \
-    FN(max_pool_quant8_1)                                        \
-    FN(max_pool_quant8_2)                                        \
-    FN(max_pool_quant8_3)                                        \
-    FN(max_pool_quant8_4)                                        \
-    FN(mean)                                                     \
-    FN(mean_float_1)                                             \
-    FN(mean_float_1_relaxed)                                     \
-    FN(mean_float_2)                                             \
-    FN(mean_float_2_relaxed)                                     \
-    FN(mean_quant8_1)                                            \
-    FN(mean_quant8_2)                                            \
-    FN(mean_relaxed)                                             \
-    FN(mobilenet_224_gender_basic_fixed)                         \
-    FN(mobilenet_224_gender_basic_fixed_relaxed)                 \
-    FN(mobilenet_quantized)                                      \
-    FN(mul)                                                      \
-    FN(mul_broadcast_quant8)                                     \
-    FN(mul_quant8)                                               \
-    FN(mul_relaxed)                                              \
-    FN(mul_relu)                                                 \
-    FN(mul_relu_relaxed)                                         \
-    FN(pad)                                                      \
-    FN(pad_float_1)                                              \
-    FN(pad_float_1_relaxed)                                      \
-    FN(pad_relaxed)                                              \
-    FN(relu1_float_1)                                            \
-    FN(relu1_float_1_relaxed)                                    \
-    FN(relu1_float_2)                                            \
-    FN(relu1_float_2_relaxed)                                    \
-    FN(relu1_quant8_1)                                           \
-    FN(relu1_quant8_2)                                           \
-    FN(relu6_float_1)                                            \
-    FN(relu6_float_1_relaxed)                                    \
-    FN(relu6_float_2)                                            \
-    FN(relu6_float_2_relaxed)                                    \
-    FN(relu6_quant8_1)                                           \
-    FN(relu6_quant8_2)                                           \
-    FN(relu_float_1)                                             \
-    FN(relu_float_1_relaxed)                                     \
-    FN(relu_float_2)                                             \
-    FN(relu_float_2_relaxed)                                     \
-    FN(relu_quant8_1)                                            \
-    FN(relu_quant8_2)                                            \
-    FN(reshape)                                                  \
-    FN(reshape_quant8)                                           \
-    FN(reshape_quant8_weights_as_inputs)                         \
-    FN(reshape_relaxed)                                          \
-    FN(reshape_weights_as_inputs)                                \
-    FN(reshape_weights_as_inputs_relaxed)                        \
-    FN(resize_bilinear)                                          \
-    FN(resize_bilinear_2)                                        \
-    FN(resize_bilinear_2_relaxed)                                \
-    FN(resize_bilinear_relaxed)                                  \
-    FN(rnn)                                                      \
-    FN(rnn_relaxed)                                              \
-    FN(rnn_state)                                                \
-    FN(rnn_state_relaxed)                                        \
-    FN(softmax_float_1)                                          \
-    FN(softmax_float_1_relaxed)                                  \
-    FN(softmax_float_2)                                          \
-    FN(softmax_float_2_relaxed)                                  \
-    FN(softmax_quant8_1)                                         \
-    FN(softmax_quant8_2)                                         \
-    FN(space_to_batch)                                           \
-    FN(space_to_batch_float_1)                                   \
-    FN(space_to_batch_float_1_relaxed)                           \
-    FN(space_to_batch_float_2)                                   \
-    FN(space_to_batch_float_2_relaxed)                           \
-    FN(space_to_batch_float_3)                                   \
-    FN(space_to_batch_float_3_relaxed)                           \
-    FN(space_to_batch_quant8_1)                                  \
-    FN(space_to_batch_quant8_2)                                  \
-    FN(space_to_batch_quant8_3)                                  \
-    FN(space_to_batch_relaxed)                                   \
-    FN(space_to_depth_float_1)                                   \
-    FN(space_to_depth_float_1_relaxed)                           \
-    FN(space_to_depth_float_2)                                   \
-    FN(space_to_depth_float_2_relaxed)                           \
-    FN(space_to_depth_float_3)                                   \
-    FN(space_to_depth_float_3_relaxed)                           \
-    FN(space_to_depth_quant8_1)                                  \
-    FN(space_to_depth_quant8_2)                                  \
-    FN(squeeze)                                                  \
-    FN(squeeze_float_1)                                          \
-    FN(squeeze_float_1_relaxed)                                  \
-    FN(squeeze_quant8_1)                                         \
-    FN(squeeze_relaxed)                                          \
-    FN(strided_slice)                                            \
-    FN(strided_slice_float_1)                                    \
-    FN(strided_slice_float_10)                                   \
-    FN(strided_slice_float_10_relaxed)                           \
-    FN(strided_slice_float_11)                                   \
-    FN(strided_slice_float_11_relaxed)                           \
-    FN(strided_slice_float_1_relaxed)                            \
-    FN(strided_slice_float_2)                                    \
-    FN(strided_slice_float_2_relaxed)                            \
-    FN(strided_slice_float_3)                                    \
-    FN(strided_slice_float_3_relaxed)                            \
-    FN(strided_slice_float_4)                                    \
-    FN(strided_slice_float_4_relaxed)                            \
-    FN(strided_slice_float_5)                                    \
-    FN(strided_slice_float_5_relaxed)                            \
-    FN(strided_slice_float_6)                                    \
-    FN(strided_slice_float_6_relaxed)                            \
-    FN(strided_slice_float_7)                                    \
-    FN(strided_slice_float_7_relaxed)                            \
-    FN(strided_slice_float_8)                                    \
-    FN(strided_slice_float_8_relaxed)                            \
-    FN(strided_slice_float_9)                                    \
-    FN(strided_slice_float_9_relaxed)                            \
-    FN(strided_slice_qaunt8_10)                                  \
-    FN(strided_slice_qaunt8_11)                                  \
-    FN(strided_slice_quant8_1)                                   \
-    FN(strided_slice_quant8_2)                                   \
-    FN(strided_slice_quant8_3)                                   \
-    FN(strided_slice_quant8_4)                                   \
-    FN(strided_slice_quant8_5)                                   \
-    FN(strided_slice_quant8_6)                                   \
-    FN(strided_slice_quant8_7)                                   \
-    FN(strided_slice_quant8_8)                                   \
-    FN(strided_slice_quant8_9)                                   \
-    FN(strided_slice_relaxed)                                    \
-    FN(sub)                                                      \
-    FN(sub_broadcast_float)                                      \
-    FN(sub_broadcast_float_relaxed)                              \
-    FN(sub_relaxed)                                              \
-    FN(svdf)                                                     \
-    FN(svdf2)                                                    \
-    FN(svdf2_relaxed)                                            \
-    FN(svdf_relaxed)                                             \
-    FN(svdf_state)                                               \
-    FN(svdf_state_relaxed)                                       \
-    FN(tanh)                                                     \
-    FN(tanh_relaxed)                                             \
-    FN(transpose)                                                \
-    FN(transpose_float_1)                                        \
-    FN(transpose_float_1_relaxed)                                \
-    FN(transpose_quant8_1)                                       \
-    FN(transpose_relaxed)
+#define FOR_EACH_TEST_MODEL(FN) FN(random_multinomial)
 
 #define FORWARD_DECLARE_GENERATED_OBJECTS(function) \
     namespace function {                            \
diff --git a/neuralnetworks/1.2/vts/functional/ModelsV1_0.h b/neuralnetworks/1.2/vts/functional/ModelsV1_0.h
new file mode 100644
index 0000000..e81e64b
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/ModelsV1_0.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VTS_HAL_NEURALNETWORKS_V1_2_VTS_FUNCTIONAL_MODELS_V1_0_H
+#define VTS_HAL_NEURALNETWORKS_V1_2_VTS_FUNCTIONAL_MODELS_V1_0_H
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "TestHarness.h"
+
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_2 {
+namespace vts {
+namespace functional {
+
+using MixedTypedExample = test_helper::MixedTypedExample;
+
+#define FOR_EACH_TEST_MODEL(FN)                          \
+    FN(add_broadcast_quant8)                             \
+    FN(add)                                              \
+    FN(add_quant8)                                       \
+    FN(avg_pool_float_1)                                 \
+    FN(avg_pool_float_2)                                 \
+    FN(avg_pool_float_3)                                 \
+    FN(avg_pool_float_4)                                 \
+    FN(avg_pool_float_5)                                 \
+    FN(avg_pool_quant8_1)                                \
+    FN(avg_pool_quant8_2)                                \
+    FN(avg_pool_quant8_3)                                \
+    FN(avg_pool_quant8_4)                                \
+    FN(avg_pool_quant8_5)                                \
+    FN(concat_float_1)                                   \
+    FN(concat_float_2)                                   \
+    FN(concat_float_3)                                   \
+    FN(concat_quant8_1)                                  \
+    FN(concat_quant8_2)                                  \
+    FN(concat_quant8_3)                                  \
+    FN(conv_1_h3_w2_SAME)                                \
+    FN(conv_1_h3_w2_VALID)                               \
+    FN(conv_3_h3_w2_SAME)                                \
+    FN(conv_3_h3_w2_VALID)                               \
+    FN(conv_float_2)                                     \
+    FN(conv_float_channels)                              \
+    FN(conv_float_channels_weights_as_inputs)            \
+    FN(conv_float_large)                                 \
+    FN(conv_float_large_weights_as_inputs)               \
+    FN(conv_float)                                       \
+    FN(conv_float_weights_as_inputs)                     \
+    FN(conv_quant8_2)                                    \
+    FN(conv_quant8_channels)                             \
+    FN(conv_quant8_channels_weights_as_inputs)           \
+    FN(conv_quant8_large)                                \
+    FN(conv_quant8_large_weights_as_inputs)              \
+    FN(conv_quant8)                                      \
+    FN(conv_quant8_overflow)                             \
+    FN(conv_quant8_overflow_weights_as_inputs)           \
+    FN(conv_quant8_weights_as_inputs)                    \
+    FN(depth_to_space_float_1)                           \
+    FN(depth_to_space_float_2)                           \
+    FN(depth_to_space_float_3)                           \
+    FN(depth_to_space_quant8_1)                          \
+    FN(depth_to_space_quant8_2)                          \
+    FN(depthwise_conv2d_float_2)                         \
+    FN(depthwise_conv2d_float_large_2)                   \
+    FN(depthwise_conv2d_float_large_2_weights_as_inputs) \
+    FN(depthwise_conv2d_float_large)                     \
+    FN(depthwise_conv2d_float_large_weights_as_inputs)   \
+    FN(depthwise_conv2d_float)                           \
+    FN(depthwise_conv2d_float_weights_as_inputs)         \
+    FN(depthwise_conv2d_quant8_2)                        \
+    FN(depthwise_conv2d_quant8_large)                    \
+    FN(depthwise_conv2d_quant8_large_weights_as_inputs)  \
+    FN(depthwise_conv2d_quant8)                          \
+    FN(depthwise_conv2d_quant8_weights_as_inputs)        \
+    FN(depthwise_conv)                                   \
+    FN(dequantize)                                       \
+    FN(embedding_lookup)                                 \
+    FN(floor)                                            \
+    FN(fully_connected_float_2)                          \
+    FN(fully_connected_float_large)                      \
+    FN(fully_connected_float_large_weights_as_inputs)    \
+    FN(fully_connected_float)                            \
+    FN(fully_connected_float_weights_as_inputs)          \
+    FN(fully_connected_quant8_2)                         \
+    FN(fully_connected_quant8_large)                     \
+    FN(fully_connected_quant8_large_weights_as_inputs)   \
+    FN(fully_connected_quant8)                           \
+    FN(fully_connected_quant8_weights_as_inputs)         \
+    FN(hashtable_lookup_float)                           \
+    FN(hashtable_lookup_quant8)                          \
+    FN(l2_normalization_2)                               \
+    FN(l2_normalization_large)                           \
+    FN(l2_normalization)                                 \
+    FN(l2_pool_float_2)                                  \
+    FN(l2_pool_float_large)                              \
+    FN(l2_pool_float)                                    \
+    FN(local_response_norm_float_1)                      \
+    FN(local_response_norm_float_2)                      \
+    FN(local_response_norm_float_3)                      \
+    FN(local_response_norm_float_4)                      \
+    FN(logistic_float_1)                                 \
+    FN(logistic_float_2)                                 \
+    FN(logistic_quant8_1)                                \
+    FN(logistic_quant8_2)                                \
+    FN(lsh_projection_2)                                 \
+    FN(lsh_projection)                                   \
+    FN(lsh_projection_weights_as_inputs)                 \
+    FN(lstm2)                                            \
+    FN(lstm2_state2)                                     \
+    FN(lstm2_state)                                      \
+    FN(lstm3)                                            \
+    FN(lstm3_state2)                                     \
+    FN(lstm3_state3)                                     \
+    FN(lstm3_state)                                      \
+    FN(lstm)                                             \
+    FN(lstm_state2)                                      \
+    FN(lstm_state)                                       \
+    FN(max_pool_float_1)                                 \
+    FN(max_pool_float_2)                                 \
+    FN(max_pool_float_3)                                 \
+    FN(max_pool_float_4)                                 \
+    FN(max_pool_quant8_1)                                \
+    FN(max_pool_quant8_2)                                \
+    FN(max_pool_quant8_3)                                \
+    FN(max_pool_quant8_4)                                \
+    FN(mobilenet_224_gender_basic_fixed)                 \
+    FN(mobilenet_quantized)                              \
+    FN(mul_broadcast_quant8)                             \
+    FN(mul)                                              \
+    FN(mul_quant8)                                       \
+    FN(mul_relu)                                         \
+    FN(relu1_float_1)                                    \
+    FN(relu1_float_2)                                    \
+    FN(relu1_quant8_1)                                   \
+    FN(relu1_quant8_2)                                   \
+    FN(relu6_float_1)                                    \
+    FN(relu6_float_2)                                    \
+    FN(relu6_quant8_1)                                   \
+    FN(relu6_quant8_2)                                   \
+    FN(relu_float_1)                                     \
+    FN(relu_float_2)                                     \
+    FN(relu_quant8_1)                                    \
+    FN(relu_quant8_2)                                    \
+    FN(reshape)                                          \
+    FN(reshape_quant8)                                   \
+    FN(reshape_quant8_weights_as_inputs)                 \
+    FN(reshape_weights_as_inputs)                        \
+    FN(resize_bilinear_2)                                \
+    FN(resize_bilinear)                                  \
+    FN(rnn)                                              \
+    FN(rnn_state)                                        \
+    FN(softmax_float_1)                                  \
+    FN(softmax_float_2)                                  \
+    FN(softmax_quant8_1)                                 \
+    FN(softmax_quant8_2)                                 \
+    FN(space_to_depth_float_1)                           \
+    FN(space_to_depth_float_2)                           \
+    FN(space_to_depth_float_3)                           \
+    FN(space_to_depth_quant8_1)                          \
+    FN(space_to_depth_quant8_2)                          \
+    FN(svdf2)                                            \
+    FN(svdf)                                             \
+    FN(svdf_state)                                       \
+    FN(tanh)
+
+#define FORWARD_DECLARE_GENERATED_OBJECTS(function) \
+    namespace function {                            \
+    extern std::vector<MixedTypedExample> examples; \
+    Model createTestModel();                        \
+    }
+
+FOR_EACH_TEST_MODEL(FORWARD_DECLARE_GENERATED_OBJECTS)
+
+#undef FORWARD_DECLARE_GENERATED_OBJECTS
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_2
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+#endif  // VTS_HAL_NEURALNETWORKS_V1_2_VTS_FUNCTIONAL_MODELS_V1_0_H
diff --git a/neuralnetworks/1.2/vts/functional/ModelsV1_1.h b/neuralnetworks/1.2/vts/functional/ModelsV1_1.h
new file mode 100644
index 0000000..eb68de4
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/ModelsV1_1.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VTS_HAL_NEURALNETWORKS_V1_1_VTS_FUNCTIONAL_MODELS_H
+#define VTS_HAL_NEURALNETWORKS_V1_1_VTS_FUNCTIONAL_MODELS_H
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "TestHarness.h"
+
+#include <android/hardware/neuralnetworks/1.2/types.h>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_2 {
+namespace vts {
+namespace functional {
+
+using MixedTypedExample = test_helper::MixedTypedExample;
+
+#define FOR_EACH_TEST_MODEL(FN)                                  \
+    FN(add_relaxed)                                              \
+    FN(avg_pool_float_1_relaxed)                                 \
+    FN(avg_pool_float_2_relaxed)                                 \
+    FN(avg_pool_float_3_relaxed)                                 \
+    FN(avg_pool_float_4_relaxed)                                 \
+    FN(avg_pool_float_5_relaxed)                                 \
+    FN(batch_to_space)                                           \
+    FN(batch_to_space_float_1)                                   \
+    FN(batch_to_space_float_1_relaxed)                           \
+    FN(batch_to_space_quant8_1)                                  \
+    FN(batch_to_space_relaxed)                                   \
+    FN(concat_float_1_relaxed)                                   \
+    FN(concat_float_2_relaxed)                                   \
+    FN(concat_float_3_relaxed)                                   \
+    FN(conv_1_h3_w2_SAME_relaxed)                                \
+    FN(conv_1_h3_w2_VALID_relaxed)                               \
+    FN(conv_3_h3_w2_SAME_relaxed)                                \
+    FN(conv_3_h3_w2_VALID_relaxed)                               \
+    FN(conv_float_2_relaxed)                                     \
+    FN(conv_float_channels_relaxed)                              \
+    FN(conv_float_channels_weights_as_inputs_relaxed)            \
+    FN(conv_float_large_relaxed)                                 \
+    FN(conv_float_large_weights_as_inputs_relaxed)               \
+    FN(conv_float_relaxed)                                       \
+    FN(conv_float_weights_as_inputs_relaxed)                     \
+    FN(depth_to_space_float_1_relaxed)                           \
+    FN(depth_to_space_float_2_relaxed)                           \
+    FN(depth_to_space_float_3_relaxed)                           \
+    FN(depthwise_conv2d_float_2_relaxed)                         \
+    FN(depthwise_conv2d_float_large_2_relaxed)                   \
+    FN(depthwise_conv2d_float_large_2_weights_as_inputs_relaxed) \
+    FN(depthwise_conv2d_float_large_relaxed)                     \
+    FN(depthwise_conv2d_float_large_weights_as_inputs_relaxed)   \
+    FN(depthwise_conv2d_float_relaxed)                           \
+    FN(depthwise_conv2d_float_weights_as_inputs_relaxed)         \
+    FN(depthwise_conv_relaxed)                                   \
+    FN(dequantize_relaxed)                                       \
+    FN(div)                                                      \
+    FN(div_broadcast_float)                                      \
+    FN(div_broadcast_float_relaxed)                              \
+    FN(div_relaxed)                                              \
+    FN(embedding_lookup_relaxed)                                 \
+    FN(floor_relaxed)                                            \
+    FN(fully_connected_float_2_relaxed)                          \
+    FN(fully_connected_float_4d_simple)                          \
+    FN(fully_connected_float_4d_simple_relaxed)                  \
+    FN(fully_connected_float_large_relaxed)                      \
+    FN(fully_connected_float_large_weights_as_inputs_relaxed)    \
+    FN(fully_connected_float_relaxed)                            \
+    FN(fully_connected_float_weights_as_inputs_relaxed)          \
+    FN(hashtable_lookup_float_relaxed)                           \
+    FN(l2_normalization_2_relaxed)                               \
+    FN(l2_normalization_large_relaxed)                           \
+    FN(l2_normalization_relaxed)                                 \
+    FN(l2_pool_float_2_relaxed)                                  \
+    FN(l2_pool_float_large_relaxed)                              \
+    FN(l2_pool_float_relaxed)                                    \
+    FN(local_response_norm_float_1_relaxed)                      \
+    FN(local_response_norm_float_2_relaxed)                      \
+    FN(local_response_norm_float_3_relaxed)                      \
+    FN(local_response_norm_float_4_relaxed)                      \
+    FN(logistic_float_1_relaxed)                                 \
+    FN(logistic_float_2_relaxed)                                 \
+    FN(lsh_projection_2_relaxed)                                 \
+    FN(lsh_projection_relaxed)                                   \
+    FN(lsh_projection_weights_as_inputs_relaxed)                 \
+    FN(lstm2_relaxed)                                            \
+    FN(lstm2_state2_relaxed)                                     \
+    FN(lstm2_state_relaxed)                                      \
+    FN(lstm3_relaxed)                                            \
+    FN(lstm3_state2_relaxed)                                     \
+    FN(lstm3_state3_relaxed)                                     \
+    FN(lstm3_state_relaxed)                                      \
+    FN(lstm_relaxed)                                             \
+    FN(lstm_state2_relaxed)                                      \
+    FN(lstm_state_relaxed)                                       \
+    FN(max_pool_float_1_relaxed)                                 \
+    FN(max_pool_float_2_relaxed)                                 \
+    FN(max_pool_float_3_relaxed)                                 \
+    FN(max_pool_float_4_relaxed)                                 \
+    FN(mean)                                                     \
+    FN(mean_float_1)                                             \
+    FN(mean_float_1_relaxed)                                     \
+    FN(mean_float_2)                                             \
+    FN(mean_float_2_relaxed)                                     \
+    FN(mean_quant8_1)                                            \
+    FN(mean_quant8_2)                                            \
+    FN(mean_relaxed)                                             \
+    FN(mobilenet_224_gender_basic_fixed_relaxed)                 \
+    FN(mul_relaxed)                                              \
+    FN(mul_relu_relaxed)                                         \
+    FN(pad)                                                      \
+    FN(pad_float_1)                                              \
+    FN(pad_float_1_relaxed)                                      \
+    FN(pad_relaxed)                                              \
+    FN(relu1_float_1_relaxed)                                    \
+    FN(relu1_float_2_relaxed)                                    \
+    FN(relu6_float_1_relaxed)                                    \
+    FN(relu6_float_2_relaxed)                                    \
+    FN(relu_float_1_relaxed)                                     \
+    FN(relu_float_2_relaxed)                                     \
+    FN(reshape_relaxed)                                          \
+    FN(reshape_weights_as_inputs_relaxed)                        \
+    FN(resize_bilinear_2_relaxed)                                \
+    FN(resize_bilinear_relaxed)                                  \
+    FN(rnn_relaxed)                                              \
+    FN(rnn_state_relaxed)                                        \
+    FN(softmax_float_1_relaxed)                                  \
+    FN(softmax_float_2_relaxed)                                  \
+    FN(space_to_batch)                                           \
+    FN(space_to_batch_float_1)                                   \
+    FN(space_to_batch_float_1_relaxed)                           \
+    FN(space_to_batch_float_2)                                   \
+    FN(space_to_batch_float_2_relaxed)                           \
+    FN(space_to_batch_float_3)                                   \
+    FN(space_to_batch_float_3_relaxed)                           \
+    FN(space_to_batch_quant8_1)                                  \
+    FN(space_to_batch_quant8_2)                                  \
+    FN(space_to_batch_quant8_3)                                  \
+    FN(space_to_batch_relaxed)                                   \
+    FN(space_to_depth_float_1_relaxed)                           \
+    FN(space_to_depth_float_2_relaxed)                           \
+    FN(space_to_depth_float_3_relaxed)                           \
+    FN(squeeze)                                                  \
+    FN(squeeze_float_1)                                          \
+    FN(squeeze_float_1_relaxed)                                  \
+    FN(squeeze_quant8_1)                                         \
+    FN(squeeze_relaxed)                                          \
+    FN(strided_slice)                                            \
+    FN(strided_slice_float_1)                                    \
+    FN(strided_slice_float_10)                                   \
+    FN(strided_slice_float_10_relaxed)                           \
+    FN(strided_slice_float_11)                                   \
+    FN(strided_slice_float_11_relaxed)                           \
+    FN(strided_slice_float_1_relaxed)                            \
+    FN(strided_slice_float_2)                                    \
+    FN(strided_slice_float_2_relaxed)                            \
+    FN(strided_slice_float_3)                                    \
+    FN(strided_slice_float_3_relaxed)                            \
+    FN(strided_slice_float_4)                                    \
+    FN(strided_slice_float_4_relaxed)                            \
+    FN(strided_slice_float_5)                                    \
+    FN(strided_slice_float_5_relaxed)                            \
+    FN(strided_slice_float_6)                                    \
+    FN(strided_slice_float_6_relaxed)                            \
+    FN(strided_slice_float_7)                                    \
+    FN(strided_slice_float_7_relaxed)                            \
+    FN(strided_slice_float_8)                                    \
+    FN(strided_slice_float_8_relaxed)                            \
+    FN(strided_slice_float_9)                                    \
+    FN(strided_slice_float_9_relaxed)                            \
+    FN(strided_slice_qaunt8_10)                                  \
+    FN(strided_slice_qaunt8_11)                                  \
+    FN(strided_slice_quant8_1)                                   \
+    FN(strided_slice_quant8_2)                                   \
+    FN(strided_slice_quant8_3)                                   \
+    FN(strided_slice_quant8_4)                                   \
+    FN(strided_slice_quant8_5)                                   \
+    FN(strided_slice_quant8_6)                                   \
+    FN(strided_slice_quant8_7)                                   \
+    FN(strided_slice_quant8_8)                                   \
+    FN(strided_slice_quant8_9)                                   \
+    FN(strided_slice_relaxed)                                    \
+    FN(sub)                                                      \
+    FN(sub_broadcast_float)                                      \
+    FN(sub_broadcast_float_relaxed)                              \
+    FN(sub_relaxed)                                              \
+    FN(svdf2_relaxed)                                            \
+    FN(svdf_relaxed)                                             \
+    FN(svdf_state_relaxed)                                       \
+    FN(tanh_relaxed)                                             \
+    FN(transpose)                                                \
+    FN(transpose_float_1)                                        \
+    FN(transpose_float_1_relaxed)                                \
+    FN(transpose_quant8_1)                                       \
+    FN(transpose_relaxed)
+
+#define FORWARD_DECLARE_GENERATED_OBJECTS(function) \
+    namespace function {                            \
+    extern std::vector<MixedTypedExample> examples; \
+    Model createTestModel();                        \
+    }
+
+FOR_EACH_TEST_MODEL(FORWARD_DECLARE_GENERATED_OBJECTS)
+
+#undef FORWARD_DECLARE_GENERATED_OBJECTS
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_2
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+#endif  // VTS_HAL_NEURALNETWORKS_V1_2_VTS_FUNCTIONAL_MODELS_V1_1_H
diff --git a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
index b840199..c1c6e55 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
@@ -479,8 +479,22 @@
 
 ///////////////////////// ADD OPERATION INPUT /////////////////////////
 
+static bool addOperationInputSkip(const Operation& operation) {
+    // Skip addOperationInputTest for the following operations.
+    // L2_NORMALIZATION, LOCAL_RESPONSE_NORMALIZATION, SOFTMAX can have an optional axis parameter.
+    if (operation.type == OperationType::L2_NORMALIZATION ||
+        operation.type == OperationType::LOCAL_RESPONSE_NORMALIZATION ||
+        operation.type == OperationType::SOFTMAX) {
+        return true;
+    }
+    return false;
+}
+
 static void addOperationInputTest(const sp<IDevice>& device, const Model& model) {
     for (size_t operation = 0; operation < model.operations.size(); ++operation) {
+        if (addOperationInputSkip(model.operations[operation])) {
+            continue;
+        }
         const std::string message = "addOperationInputTest: operation " + std::to_string(operation);
         validate(device, message, model, [operation](Model* model) {
             uint32_t index = addOperand(model, OperandLifeTime::MODEL_INPUT);
diff --git a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
index f4476fa..b663535 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
@@ -38,7 +38,7 @@
 using ::android::hidl::memory::V1_0::IMemory;
 using test_helper::for_all;
 using test_helper::MixedTyped;
-using test_helper::MixedTypedExampleType;
+using test_helper::MixedTypedExample;
 
 ///////////////////////// UTILITY FUNCTIONS /////////////////////////
 
@@ -152,15 +152,15 @@
 
 ///////////////////////////// ENTRY POINT //////////////////////////////////
 
-std::vector<Request> createRequests(const std::vector<MixedTypedExampleType>& examples) {
+std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples) {
     const uint32_t INPUT = 0;
     const uint32_t OUTPUT = 1;
 
     std::vector<Request> requests;
 
     for (auto& example : examples) {
-        const MixedTyped& inputs = example.first;
-        const MixedTyped& outputs = example.second;
+        const MixedTyped& inputs = example.operands.first;
+        const MixedTyped& outputs = example.operands.second;
 
         std::vector<RequestArgument> inputs_info, outputs_info;
         uint32_t inputSize = 0, outputSize = 0;
diff --git a/neuralnetworks/1.2/vts/functional/ValidationTestsV1_0.cpp b/neuralnetworks/1.2/vts/functional/ValidationTestsV1_0.cpp
new file mode 100644
index 0000000..c54ed43
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/ValidationTestsV1_0.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "ModelsV1_0.h"
+#include "VtsHalNeuralnetworks.h"
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_2 {
+namespace vts {
+namespace functional {
+
+// forward declarations
+std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
+
+// generate validation tests
+#define VTS_CURRENT_TEST_CASE(TestName)                                           \
+    TEST_F(ValidationTest, TestName) {                                            \
+        const Model model = TestName::createTestModel();                          \
+        const std::vector<Request> requests = createRequests(TestName::examples); \
+        validateModel(model);                                                     \
+        validateRequests(model, requests);                                        \
+    }
+
+FOR_EACH_TEST_MODEL(VTS_CURRENT_TEST_CASE)
+
+#undef VTS_CURRENT_TEST_CASE
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_2
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/neuralnetworks/1.2/vts/functional/ValidationTestsV1_1.cpp b/neuralnetworks/1.2/vts/functional/ValidationTestsV1_1.cpp
new file mode 100644
index 0000000..95932d5
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/ValidationTestsV1_1.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "ModelsV1_1.h"
+#include "VtsHalNeuralnetworks.h"
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_2 {
+namespace vts {
+namespace functional {
+
+// forward declarations
+std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
+
+// generate validation tests
+#define VTS_CURRENT_TEST_CASE(TestName)                                           \
+    TEST_F(ValidationTest, TestName) {                                            \
+        const Model model = TestName::createTestModel();                          \
+        const std::vector<Request> requests = createRequests(TestName::examples); \
+        validateModel(model);                                                     \
+        validateRequests(model, requests);                                        \
+    }
+
+FOR_EACH_TEST_MODEL(VTS_CURRENT_TEST_CASE)
+
+#undef VTS_CURRENT_TEST_CASE
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_2
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/power/stats/1.0/Android.bp b/power/stats/1.0/Android.bp
index 2f16a21..9a956e4 100644
--- a/power/stats/1.0/Android.bp
+++ b/power/stats/1.0/Android.bp
@@ -14,9 +14,15 @@
         "android.hidl.base@1.0",
     ],
     types: [
-        "Status",
-        "RailInfo",
         "EnergyData",
+        "PowerEntityInfo",
+        "PowerEntityStateInfo",
+        "PowerEntityStateResidencyData",
+        "PowerEntityStateResidencyResult",
+        "PowerEntityStateSpace",
+        "PowerEntityType",
+        "RailInfo",
+        "Status",
     ],
     gen_java: false,
 }
diff --git a/power/stats/1.0/IPowerStats.hal b/power/stats/1.0/IPowerStats.hal
index d75e170..75c6a72 100644
--- a/power/stats/1.0/IPowerStats.hal
+++ b/power/stats/1.0/IPowerStats.hal
@@ -50,10 +50,13 @@
      * asynchronous.
      *
      * @param timeMs Time(in ms) for which energyData should be streamed
-     * @return mqDesc Unsynchronous Fast Message Queue descriptor - One
-     *     writer(power.stats HAL) multiple readers are supported. Reader
-     *     should read faster than writer otherwise data might be
-     *     overwritten. Data is present in following format in the queue:
+     * @param samplingRate Frequency(in Hz) at which samples should be
+     *     captured. If the requested sampling rate is not supported then
+     *     SUCCESS is returned and numSamples are reported back according
+     *     to the supported sampling rate.
+     * @return mqDesc Blocking Synchronous Fast Message Queue descriptor - One
+     *     writer(power.stats HAL) and one reader are supported. Data is
+     *     present in the following format in the queue:
      *     +-----------------------+       <--
      *     | EnergyData for rail 1 |         |
      *     +-----------------------+         |
@@ -87,9 +90,73 @@
      * @return numSamples Number of samples which will be generated in timeMs.
      * @return railsPerSample Number of rails measured per sample.
      * @return status SUCCESS on success or FILESYSTEM_ERROR on filesystem
-     *     nodes access or NOT_SUPPORTED if feature is not enabled.
+     *     nodes access or NOT_SUPPORTED if feature is not enabled or
+     *     INSUFFICIENT_RESOURCES if there are not enough resources.
      */
-    streamEnergyData(uint32_t timeMs)
-        generates(fmq_unsync<EnergyData> mqDesc, uint32_t numSamples,
+    streamEnergyData(uint32_t timeMs, uint32_t samplingRate)
+        generates(fmq_sync<EnergyData> mqDesc, uint32_t numSamples,
                 uint32_t railsPerSample, Status status);
+
+    /**
+     * PowerEntity information:
+     * Reports information related to all supported PowerEntity(s) for which
+     * data is available. A PowerEntity is defined as a platform subsystem,
+     * peripheral, or power domain that impacts the total device power
+     * consumption.
+     *
+     * @return powerEntityInfos List of information on each PowerEntity
+     * @return status SUCCESS on success or NOT_SUPPORTED if
+     *     feature is not enabled or FILESYSTEM_ERROR on filesystem nodes
+     *     access error.
+     */
+    getPowerEntityInfo()
+        generates(vec<PowerEntityInfo> powerEntityInfos, Status status);
+
+    /**
+     * PowerEntity state information:
+     * Reports the set of power states for which the specified
+     * PowerEntity(s) provide residency data.
+     *
+     * @param powerEntityIds collection of IDs of PowerEntity(s) for which
+     *     state information is requested. PowerEntity name to ID mapping may
+     *     be queried from getPowerEntityInfo(). To get state space
+     *     information for all PowerEntity(s) pass an empty vector.
+     *
+     * @return powerEntityStateSpaces PowerEntity state space information for
+     *     each specified PowerEntity.
+     * @return status SUCCESS if powerEntityStateInfos contains state space
+     *     information for at least one PowerEntity, NOT_SUPPORTED if feature
+     *     is not enabled, INVALID_INPUT if no requested PowerEntity(s)
+     *     provide state space information, FILESYSTEM_ERROR if no state space
+     *     information is returned due to filesystem errors.
+     */
+    getPowerEntityStateInfo(vec<uint32_t> powerEntityIds)
+        generates(vec<PowerEntityStateSpace> powerEntityStateSpaces,
+                  Status status);
+
+    /**
+     * PowerEntity residencies for low frequency clients:
+     * Reports accumulated residency data for each specified PowerEntity.
+     * Each PowerEntity may reside in one of multiple states. It may also
+     * transition to another state. Residency data is an accumulation of time
+     * that a specified PowerEntity resided in each of its possible states,
+     * the number of times that each state was entered, and a timestamp
+     * corresponding to the last time that state was entered. Data is
+     * accumulated starting from the last time the PowerEntity was reset.
+     *
+     * @param powerEntityId collection of IDs of PowerEntity(s) for which
+     *     residency data is requested. PowerEntity name to ID mapping may
+     *     be queried from getPowerEntityInfo(). To get state residency
+     *     data for all PowerEntity(s) pass an empty vector.
+     * @return stateResidencyResults state residency data for the
+     *     specified powerEntity(s)
+     * @return status SUCCESS if stateResidencyResults contains residency
+     *     data for at least one PowerEntity, NOT_SUPPORTED if
+     *     feature is not enabled, INVALID_INPUT if no requested
+     *     PowerEntity(s) provide state residency data, FILESYSTEM_ERROR
+     *     if no data is returned due to filesystem errors.
+     */
+    getPowerEntityStateResidencyData(vec<uint32_t> powerEntityIds)
+        generates(vec<PowerEntityStateResidencyResult> stateResidencyResults,
+                  Status status);
 };
diff --git a/power/stats/1.0/types.hal b/power/stats/1.0/types.hal
index 826c29b..986a6bb 100644
--- a/power/stats/1.0/types.hal
+++ b/power/stats/1.0/types.hal
@@ -20,6 +20,7 @@
     NOT_SUPPORTED = 1,
     INVALID_INPUT = 2,
     FILESYSTEM_ERROR = 3,
+    INSUFFICIENT_RESOURCES = 4,
 };
 
 struct RailInfo {
@@ -35,7 +36,7 @@
 
 struct EnergyData {
     /**
-     * Index corrensponding to the rail. This index matches
+     * Index corresponding to the rail. This index matches
      * the index returned in RailInfo
      */
     uint32_t index;
@@ -44,3 +45,85 @@
     /** Accumulated energy since device boot in microwatt-seconds (uWs) */
     uint64_t energy;
 };
+
+enum PowerEntityType : uint32_t {
+    /**
+     * A subsystem is a self-contained compute unit. Some examples include
+     * application processor, DSP, GPU.
+     */
+    SUBSYSTEM = 0,
+    /**
+     * A peripheral is an auxiliary device that connects to and works with a
+     * compute unit. Some examples include simple sensors, camera, display.
+     */
+    PERIPHERAL = 1,
+    /**
+     * A power domain is a single subsystem or a collection of subsystems
+     * that is controlled by a single voltage rail.
+     */
+    POWER_DOMAIN = 2,
+};
+
+/**
+ * PowerEntityInfo contains information, such as the ID, name, and type of a
+ * given PowerEntity.
+ */
+struct PowerEntityInfo {
+    /** ID corresponding to the PowerEntity */
+    uint32_t powerEntityId;
+    /**
+     * Name of the PowerEntity. This is unique and opaque to the
+     * Android framework
+     */
+    string powerEntityName;
+    /** Type of the PowerEntity */
+    PowerEntityType type;
+};
+
+struct PowerEntityStateInfo {
+    /** ID corresponding to the state */
+    uint32_t powerEntityStateId;
+    /** Name of the state */
+    string powerEntityStateName;
+};
+
+/**
+ * PowerEntityStateSpace contains the state space information of a given
+ * PowerEntity. The state space, is the set of possible states that a given
+ * PowerEntity provides residency data for.
+ */
+struct PowerEntityStateSpace {
+    /** ID of the corresponding PowerEntity */
+    uint32_t powerEntityId;
+
+    /** List of states that the PowerEntity may reside in */
+    vec<PowerEntityStateInfo> states;
+};
+
+/** Contains residency data for a single state */
+struct PowerEntityStateResidencyData {
+    /** ID of the corresponding PowerEntityStateInfo */
+    uint32_t powerEntityStateId;
+    /**
+     * Total time in milliseconds that the corresponding PowerEntity resided
+     * in this state since the PowerEntity was reset
+     */
+    uint64_t totalTimeInStateMs;
+    /**
+     * Total number of times that the state was entered since the corresponding
+     * PowerEntity was reset
+     */
+    uint64_t totalStateEntryCount;
+    /**
+     * Last time this state was entered. Time in milliseconds since the
+     * corresponding PowerEntity was reset
+     */
+    uint64_t lastEntryTimestampMs;
+};
+
+struct PowerEntityStateResidencyResult {
+    /** ID of the corresponding PowerEntity */
+    uint32_t powerEntityId;
+    /** Residency data for each state the PowerEntity's state space */
+    vec<PowerEntityStateResidencyData> stateResidencyData;
+};
diff --git a/prebuilt_hashes/26.txt b/prebuilt_hashes/26.txt
new file mode 100644
index 0000000..f2feb4c
--- /dev/null
+++ b/prebuilt_hashes/26.txt
@@ -0,0 +1,186 @@
+# Do not change this file except to add new interfaces. Changing
+# pre-existing interfaces will fail VTS and break framework-only OTAs
+
+# HALs released in Android O
+
+f219c3b5b8c6cb1d659d4c7328f67246abfe1a8613f469826fd3b9ad090417a2 android.hardware.audio@2.0::IDevice
+4d579cae1cd87a783fd49233e10ce720ba183cfd1d5ccd80149e69de5c1c7362 android.hardware.audio@2.0::IDevicesFactory
+203e23f18011390b8cd10c303e0c16c4eebc8fa187e80e40d6be4624c2b0848a android.hardware.audio@2.0::IPrimaryDevice
+aaf93123deec336eb247ad8099849469a541ca0cf7c28c5f5336cebe1ee86748 android.hardware.audio@2.0::IStream
+0468c5723b0d44c5b451bdfa06153000c6f352fd3336e0ad2697127b04b766df android.hardware.audio@2.0::IStreamIn
+7296f7064fd3ab24082b43a1da34cc876268065310b785499fba5178d063680a android.hardware.audio@2.0::IStreamOut
+19d241d71c3e1140afba8140dcb57448446025a5fc03739788c4c25e9a98b6c2 android.hardware.audio@2.0::IStreamOutCallback
+c84da9f586087227daa3b96d42b4575326bccfd5bc8a2a5acf86d774f8ea2648 android.hardware.audio@2.0::types
+1305786c06e22b9b24ebde136054cc827b63c86d8bf4a136d6f7f54752b8566b android.hardware.audio.common@2.0::types
+fa8fbae3d1da3c264e4f3110728076abc09b4e65f12af6ae136367328de988ab android.hardware.audio.effect@2.0::IAcousticEchoCancelerEffect
+ca4752545d54547ff069eae161af7550cb5f5a7e8b60316ddd132a30906a68e7 android.hardware.audio.effect@2.0::IAutomaticGainControlEffect
+d2b8af988dc66f514d886bcee44b440d8034bc2a762f7161717ef3c956073067 android.hardware.audio.effect@2.0::IBassBoostEffect
+611bc09c75e796f3512b1ca6be508b0a9ba996759b8a2c60507784ff58076229 android.hardware.audio.effect@2.0::IDownmixEffect
+36a57369dfdc75180e8b64ae80b1970db8f6d9085dbff6ca931715038cc056e1 android.hardware.audio.effect@2.0::IEffect
+d2aa2df6d189c580f5be8460fa0ff4134d9c05a383f3204659baee426a6f0edf android.hardware.audio.effect@2.0::IEffectBufferProviderCallback
+217f9161983a48d3bf3faeb158f868aa8bf0ce25889e4ee3d2bab1a2e8d33e77 android.hardware.audio.effect@2.0::IEffectsFactory
+c2b38bc07991e880c83ca8cb88181411eeef708b8b936aedd2f2e0acade7df69 android.hardware.audio.effect@2.0::IEnvironmentalReverbEffect
+2ff9f9704be5f167745b4de790e9dafc3cc4719e2f6e2e5497085e679853cfe7 android.hardware.audio.effect@2.0::IEqualizerEffect
+c31447fb02dbc8b56c359941dad22f416511860173c5c5fd278d1bf2312b13de android.hardware.audio.effect@2.0::ILoudnessEnhancerEffect
+804831ca258802eb3eb65a0a7b5d5e3d37d4a15ba8c2836b4276eda98b47e1d0 android.hardware.audio.effect@2.0::INoiseSuppressionEffect
+778fd5b9837f481d8e47425b3e2a3bd0c6362a0b6870291518e2d863530fdb61 android.hardware.audio.effect@2.0::IPresetReverbEffect
+c93cb25a1a92d07aa80a617c01e8d22fc97bf8cefd3962b6a5be386ad4704d89 android.hardware.audio.effect@2.0::IVirtualizerEffect
+918f331780c9c7b04f2151a2e563aab088198ede8e6f865302ebaa13905bd9ce android.hardware.audio.effect@2.0::IVisualizerEffect
+4caad099f8fc00262b6c03ba41271808b37cea90ac98b534299bbf4ee823af02 android.hardware.audio.effect@2.0::types
+# android.hardware.automotive.* are unfrozen
+1fbdc1f852f8bd2e4a6c5cb30ac2b78668c98dce118a61762d4034ae859f43d8 android.hardware.biometrics.fingerprint@2.1::IBiometricsFingerprint
+aabb5c3c585592d71ee57b77298c14993d77914ddeaa64b2c5109a602b02ea47 android.hardware.biometrics.fingerprint@2.1::IBiometricsFingerprintClientCallback
+1ec60d4efddae9a7b2469278a576967b4751e88de5b8d7e9df6eff6bc0da7bc9 android.hardware.biometrics.fingerprint@2.1::types
+347ce746815607567f5f3b53e4800998ca5ab9355141f0880fc0cf0c1fc5c355 android.hardware.bluetooth@1.0::IBluetoothHci
+835f41be2281bfb22f3e33c6fa870bde7bc21e37e5cfbaf9a36fff170632f754 android.hardware.bluetooth@1.0::IBluetoothHciCallbacks
+a8dfd0dbe463a3cdbcf1d985b38a28b3d93ba2ae5a1d1db4aaef4c38a5781b91 android.hardware.bluetooth@1.0::types
+7192d756aeba00aba32f4504981df8172ffca83e210c4838dabf295e53e93590 android.hardware.boot@1.0::IBootControl
+cebaa803b8e33807a0d69f46652b650ccb549e8f9b19d6becbbf26690e828b49 android.hardware.boot@1.0::types
+a98d49f23712a7cc327d1e0602d05f6f3ad32cfb5c74711d009c726611ee1c93 android.hardware.broadcastradio@1.0::IBroadcastRadio
+ed82579c0c165feaa12d0e33c06b3342ab41ec0a439247f202775e8369e46ef6 android.hardware.broadcastradio@1.0::IBroadcastRadioFactory
+da6ab32ee2793d2c86d3b603075d5383852b89d7eaa201861aa0473d418f3c7f android.hardware.broadcastradio@1.0::ITuner
+04d3ca022e25c308d9efd2e7eb77b3a7a206907cdc1b9ea9326340b377868172 android.hardware.broadcastradio@1.0::ITunerCallback
+bd42c8d7838cfed1998b49c39745dec116d2d6edc2c11a4c0399b8f3a1d1655a android.hardware.broadcastradio@1.0::types
+81164323115d6588e259e8319fddf7487adfa1f49ce60f7e80ba74e0783392a4 android.hardware.camera.common@1.0::types
+c1705e9d62438a1d955269965af915ae28e692bd480a3b1ce67056fef992d62f android.hardware.camera.device@1.0::ICameraDevice
+78e9b44cf8660bdc1e98dca07451804153824efcd28db208a62f5ad728f44076 android.hardware.camera.device@1.0::ICameraDeviceCallback
+28f0386ba86ddf41e53a8117b48a0328d7a4d2574213e89f4a1062398a244566 android.hardware.camera.device@1.0::ICameraDevicePreviewCallback
+4db48439ce9dde97f1cfb3d7408f6c737f621ac0f7494aeea35ed599bc2352a3 android.hardware.camera.device@1.0::types
+b32f9aeaf1c442195eb06ffc7600968c919d005b2718874f09c57287fae55918 android.hardware.camera.device@3.2::ICameraDevice
+63bfc3da0f2d2301f7a0508c7c2b9ffc521d4d545ee03718da70e9d6273b3b21 android.hardware.camera.device@3.2::ICameraDeviceCallback
+0fa3e1e64819283b8737fc4e5ab759f0cb4ac1a996e8a51cc4aa8025a457208e android.hardware.camera.device@3.2::ICameraDeviceSession
+030be3d2b159cbde7920485807140f6b6064ef4a5de4a40a6c4bc8d2c72f7cd3 android.hardware.camera.device@3.2::types
+5ba7947cee515d7a2359bfcbfb9678c1c3a768c288471919ac095b96ae6f3d40 android.hardware.camera.metadata@3.2::types
+f7e299d85033ac52d1095a35784fcfeaff43603f58c751e4153c85bbade3b330 android.hardware.camera.provider@2.4::ICameraProvider
+a501ca1aecd09f1b9fd70a9af84205430dbd49a808e8fa395d363b9902e6f58c android.hardware.camera.provider@2.4::ICameraProviderCallback
+7f5fe8f4f8a24037153c504d8b4d3313c2ce33d81c8c69fe5194ddd2d4080e72 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
+87beacc481897cf02fb1628d75e68133de6d74d4cffe582cda2f5e16bdd74516 android.hardware.configstore@1.0::types
+a5ae0fe8667f0b1af09b13e72d29600f4eb3853b257079c45a99b6f4a3360649 android.hardware.contexthub@1.0::IContexthub
+2ab3054c2d9302d8417ee7495353a2887fe338f913276f2eb41e80f11395ec2e android.hardware.contexthub@1.0::IContexthubCallback
+c3b2b37d561d31ea094411f251bf73bea334f4fe849a4390aef5e20bca6cadba android.hardware.contexthub@1.0::types
+df174c1871c864b4c79ca9f64aae7936d24a272eca3191a30458ca2b706dec79 android.hardware.drm@1.0::ICryptoFactory
+83639e90caeb996b0274e420de3cd556779de1ca48464b68eee799bef32b34cd android.hardware.drm@1.0::ICryptoPlugin
+1440cffdfaeb12830ac10ee6ffdb0f1083e701057b806df11fb4787b4c91e718 android.hardware.drm@1.0::IDrmFactory
+78ba33b108f620e6a0eec01ef654547e69a85754578ea4c9ef03ec205f16121c android.hardware.drm@1.0::IDrmPlugin
+701d9e51952172364e4ea70db9c397f08c3b4577ba33051f050a6cdd532de1b4 android.hardware.drm@1.0::IDrmPluginListener
+4238d62ad90df63aa338c6f1b6264c09c5a3706945d5c49d1189c0be1dc9e942 android.hardware.drm@1.0::types
+f07b1ee3ba11a2fc9f200421b2e1afb7c1854ee987000e45c987fb9507795055 android.hardware.dumpstate@1.0::IDumpstateDevice
+c9d318df7922bde3b265927b521ff5a965002826fc0cabfcaef52a56760f2d34 android.hardware.gatekeeper@1.0::IGatekeeper
+da13bd69282fb275767abb18704c57ff8038e6c139ad17157dc702810f70d06a android.hardware.gatekeeper@1.0::types
+37c7da4f823ec958dfa9c960e2d341c48f877e0bfa758f3fa9e2d9c1e1bd66d9 android.hardware.gnss@1.0::IAGnss
+7ec9afdb964bfb8369866913caf018f2636592885bcb558a65de2c5436ab4f60 android.hardware.gnss@1.0::IAGnssCallback
+d16e6a359be6963ea753d7138e84ecf2b93052097938938c4d36d7a47ea2e2ae android.hardware.gnss@1.0::IAGnssRil
+2f907708d74d94b1e121ed27651c9c72af65952d347b58ff07dac5d5d7a7f678 android.hardware.gnss@1.0::IAGnssRilCallback
+5ac7edad06d76064b882be161f3f9d9692a997ec72e9f36addb7fe8918f49992 android.hardware.gnss@1.0::IGnss
+b05c983c87c3376e145223688c3b541b5e11b827f211e38d5a31af1ca3a2e222 android.hardware.gnss@1.0::IGnssBatching
+4981d2d2c4e725c7544be0956099a91fc7bbc8048c563394158083fe924e651e android.hardware.gnss@1.0::IGnssBatchingCallback
+3cd22d92cc1f935150c5048310e84886f14eed2556e8f00636733d204045cc4f android.hardware.gnss@1.0::IGnssCallback
+175185a5eda87476193ca5461df75dd16d36664591e8130530dd8ef0eb2ddf6a android.hardware.gnss@1.0::IGnssConfiguration
+4542122b96fbf27101cb8222bafb76e7c8d032d977dd1058edd8e5881ca5752f android.hardware.gnss@1.0::IGnssDebug
+e6dd0c8416e523ab9cbd14d56ab6f016481a8aef3bc8a750051122d31075f6c7 android.hardware.gnss@1.0::IGnssGeofenceCallback
+f90e4ddc652706299d8e3d8ba18e0745c3bae9bf4d1be6bd06d9c1f50ec8d28a android.hardware.gnss@1.0::IGnssGeofencing
+9ea8987bb1089c8c5d7b67866575b866ef516045021d9efcc37c6352bce072a3 android.hardware.gnss@1.0::IGnssMeasurement
+cf20492673d6a423e4c2e87fdfb5a4c4a602431721978db852e246f258e25edb android.hardware.gnss@1.0::IGnssMeasurementCallback
+af85aa0f48ae99a39f4688c344e4419304f681f9af818a5c8d759286fc4418de android.hardware.gnss@1.0::IGnssNavigationMessage
+76b0874ea4c06b29f66418c59820f4286b3be9629cd872923d0dfbb602cd432d android.hardware.gnss@1.0::IGnssNavigationMessageCallback
+248bcf51da4273d64f367bf6877baef2feeaca365459842fd3c214a2dc6e0224 android.hardware.gnss@1.0::IGnssNi
+c781b7b125f68be5db8a8c3d412d526acdbdf77dcc592a4c0ed70b8ce4fe6c49 android.hardware.gnss@1.0::IGnssNiCallback
+c1142657de16fdb292a502372fe938614d65270ab8359217d6e13604fe4dbca4 android.hardware.gnss@1.0::IGnssXtra
+bd366b83d8d565d0e8bfabff3adfcab0259d75b4e2a9f8e1b91e11d1593a2ffb android.hardware.gnss@1.0::IGnssXtraCallback
+881bc2f94026784d194cffbff166c6e8bf911de4e02abe96fc7d89ec75b0574a android.hardware.gnss@1.0::types
+17971eb8a482893dadcfc16e0583f492d42a034ef95d9b0b709417af30838396 android.hardware.graphics.allocator@2.0::IAllocator
+60bf42a4898e4fb70dbd720b263aeafd7f35f5e1a5effeabb4d5d659878a5f18 android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer
+b8a75617b9ec12bea641f3a73d4025a33e8b9a2f9169dd46094af56adf9249c5 android.hardware.graphics.bufferqueue@1.0::IProducerListener
+4f6dedbcdd21c309dfc650acea81a096d6b242493ffe49c8d61bd3c43aad354e android.hardware.graphics.common@1.0::types
+b3aac6c3817f039964fcd62268274b3039e17bd7d0d5b40b4d1d1c7b19a1f866 android.hardware.graphics.composer@2.1::IComposer
+b19d00eb8a8b3b0034a0321f22e8f32162bf4c2aebbce6da22c025f56e459ea2 android.hardware.graphics.composer@2.1::IComposerCallback
+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
+91e2ba3805c923f01fc1231ec9ff838942aee3346f2d7614ecc0caeadbe57ed4 android.hardware.health@1.0::IHealth
+1275aa2e8732909101b26aec49ed2285489e89d97b8610a8908b7868e35a3cc5 android.hardware.health@1.0::types
+3a8d3922e06e6d4f8e0befc6be78d0e9e07aed1585b3da6521bed406d25a9483 android.hardware.ir@1.0::IConsumerIr
+7090bd37912fcf723a12f4bc17783e3527577c4944805a028c296fd7a95bd682 android.hardware.ir@1.0::types
+cc7925a78c0ab022515f48840d3dae76f384ed3a1287abadcb461a5cd5396163 android.hardware.keymaster@3.0::IKeymasterDevice
+822998d7bb76f0cd719a409291434fcb56e6d50bc4780788bb157a3374d63b8c android.hardware.keymaster@3.0::types
+d4ed2f0e14f9e914d0b1275d2e0363192fe30aca9059c84edb5fad15995f9ec4 android.hardware.light@2.0::ILight
+d9584bfcaedd6e62cf337881748246b23e36cbc2bc3aa84c01b6a1e622061400 android.hardware.light@2.0::types
+16c0cf0f73de1e5208a95020c6c6474903e7094f76b2d782651afaca0e5fd86f android.hardware.media@1.0::types
+8bc2f5fdcad68856eb61a62fe4cc043fa064bb7f1dab95a71d1918ec1eef7b55 android.hardware.media.omx@1.0::IGraphicBufferSource
+0d3de9cd89d4718ea3b772f2d8b93be004feb3abb7e7dc5402e37047cc730d05 android.hardware.media.omx@1.0::IOmx
+32002e1c358c64de106c977a6dc6af7da27be4803a5bb66fd6f891a5ba0a1617 android.hardware.media.omx@1.0::IOmxBufferSource
+81ad8d8bb1cf6f41923cf11dd39354a8fe433db284a234cc675de7e75a82224c android.hardware.media.omx@1.0::IOmxNode
+494c0c8bf6065edc82ec127228ed19dd2243dc1c2f7d601c7c6be7b7015c1713 android.hardware.media.omx@1.0::IOmxObserver
+252c2fc50c78fd6de8365e5b60e5115119ace107db0b94b0b26815cbf3d2b64a android.hardware.media.omx@1.0::IOmxStore
+148c1b50b0958988373145ffdf5fa0e1b6534e0a2034a570e74b15c127cf7c5e android.hardware.media.omx@1.0::types
+c66902fe48d687ac6740a3e32ae55fb75532c48c36c6386461c2b4416ad2e0f1 android.hardware.memtrack@1.0::IMemtrack
+860bacd8b11a269c40567542b613fe4ca448d5cb4326d0058899e608e89dfca1 android.hardware.memtrack@1.0::types
+07ac2dc95270321ec7d4c33cd25e5085a057f47fe350d645af6f7a7a11e3cf57 android.hardware.nfc@1.0::INfc
+f2fe54426c07d67388d4774a60641ad4c0538f22eb6e1111722f231772655de6 android.hardware.nfc@1.0::INfcClientCallback
+9626fd18db113d709faf593a70caf19bd0980294d23c468c80c30186f9d298a6 android.hardware.nfc@1.0::types
+deee1dc4948f33af207e1008aba0f6cc07afb7900eab53f33192c8cac137eefc android.hardware.power@1.0::IPower
+efc83df3f962b93c7c0290d691d7d300dabe12683e2cde3591fb3c0beedce20f android.hardware.power@1.0::types
+9b5aa499ec3b4226f15f48f5ed08896e2fc0676f978c9e199c1da21daaf002a6 android.hardware.radio@1.0::IRadio
+5c8efbb9c451a59737ed2c6c20230aae4745839ca01d8088d6dcc9020e52d2c5 android.hardware.radio@1.0::IRadioIndication
+69f6b4b8ec40ca02ccc7bb8227a097135c20c00bd94c822e421cd9af1267252c android.hardware.radio@1.0::IRadioResponse
+de3ab9f73b1073cd677b19d886fb927e9381b30161a704712d2b30f875873f5c android.hardware.radio@1.0::ISap
+d183e406ef0897df2117a9dde384e8e6ea4fa6ab1c7f6f28e65b87011218c9ea android.hardware.radio@1.0::ISapCallback
+96986fbd22f0e6ca752e1fcdc0a64bda213995a81f5f36bc4faf3532d9306b97 android.hardware.radio@1.0::types
+00f70085d6fae1d482fb700a3fd42ed475384c95b51c9269b9ae5037b74ad4dd android.hardware.radio.deprecated@1.0::IOemHook
+06837b6d7e843cfa9cd20fed4070feca7a9b5c81a9ed643bf7d06803455a9816 android.hardware.radio.deprecated@1.0::IOemHookIndication
+6fd4874f0eddd4626a27658fd94fad526c317f3563439e79718bdb1a3a2309d5 android.hardware.radio.deprecated@1.0::IOemHookResponse
+6983a2cafe39d5c57dfdc1743055fb0f757a0df8c78e00423d5e1810836927e1 android.hardware.renderscript@1.0::IContext
+7f9417a0ccf78ea042ec7a8ac8e3750346d4d9d7e5ae01b1b35fde303f47c24d android.hardware.renderscript@1.0::IDevice
+fc6f325b266b32353f7d1534fbe58e0d368265a12b77fa396fb556e8c443f739 android.hardware.renderscript@1.0::types
+89585ff541c319de4091a5a0b687dd526ac81c6382ffd7b979a4164b3d7419a6 android.hardware.sensors@1.0::ISensors
+e04ab978fc28f4c515f4a75617dfda8607733a64f13666beeb0e604a07a39333 android.hardware.sensors@1.0::types
+5befc019cbe94953661e2cdb95e3cf64f5e565c29403e1c2daecc2be44e0a55c android.hardware.soundtrigger@2.0::ISoundTriggerHw
+d7ec5f612a5e0a59ea4f2b61317e208ff56dd50920fd4eb441e0cbc8f97e4f49 android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
+5bee9e70f7e5ec7ee252883b28f98f12b59960f4c2a0b4cc9a4526e4669ebcd4 android.hardware.soundtrigger@2.0::types
+97f1ec446043bc5a6645b74529a6276496bdb35e0aee41eda55cb92d51eb7802 android.hardware.thermal@1.0::IThermal
+84965a6908bceb4ef51546bf8731f309f1ea9d09a0177dcc7974132e523dd6d2 android.hardware.thermal@1.0::types
+938850621c3c5ef426a4b88e752ba99b3559037e782a3d938604f3aef5cc0f1b android.hardware.tv.cec@1.0::IHdmiCec
+e75b6eea711d36fac678bce072b3cec6544b27fa9f4cd903999404e5c110ca10 android.hardware.tv.cec@1.0::IHdmiCecCallback
+6e25f8dbfadb668e1d4ec80eb9acd95d8bc9e0a240c36d27e662adb440314b95 android.hardware.tv.cec@1.0::types
+0cafa3c8388e9631916d2d800f78decbcec2904f11415b32c71a31d9a51ebf79 android.hardware.tv.input@1.0::ITvInput
+dee83e5c864fbbee8f02448d0800be32f06856386b9f907bc5d952208c9434f9 android.hardware.tv.input@1.0::ITvInputCallback
+07aab30410b612381234dca6d453d4ab96f2e536368715717c6e28101b9851b5 android.hardware.tv.input@1.0::types
+4ef57499273f38bdbdd0c15e56ee7a4bc5f18a5644092170a531df3541d9e015 android.hardware.usb@1.0::IUsb
+4be7881e411ba42784bf5b7354c14ae0cf161004d39433aaecaab0d19ea99354 android.hardware.usb@1.0::IUsbCallback
+f7e6e747910a3cd0a35846141e3b990a6a612a297b2b70ccd5740b646a450a8c android.hardware.usb@1.0::types
+06ea64cc3565777f3b259e400ffa7100d07f3827ad9357b0c5d3c651384e5553 android.hardware.vibrator@1.0::IVibrator
+0fecd34ae64f32eff6aa615fd662349242c0b8b6e303ef05a7cb5776c732f413 android.hardware.vibrator@1.0::types
+4b962968a7df4ab104d1315d66a0a7348a713fecbb5d2c1b23688494458f37ce android.hardware.vr@1.0::IVr
+b9be36719a8ad534000a51ea07be91be94c405bf1e038ae825acf65087ffd378 android.hardware.wifi@1.0::IWifi
+ee0224ee18813506d9d6f13d8c8e4679f053c290a443a52a7c52a5d3c852262b android.hardware.wifi@1.0::IWifiApIface
+f3eecc489deb4c74892f59eb7adb769063bd5c354ac132b626a5f42b363d36bc android.hardware.wifi@1.0::IWifiChip
+a1b988377645a58e5e2542ca2bad4e17c21a4a389213d05de2f0e32d57b7d339 android.hardware.wifi@1.0::IWifiChipEventCallback
+5ed6760ce77e84bc6c49d1acb3f7d8117c9176b3f06514bc44ad3af84c80dcfe android.hardware.wifi@1.0::IWifiEventCallback
+6b9ad43a5efbe6ca214f751e22ce43cf5cd4d5d5f2cba80f24ccd3755a72401c android.hardware.wifi@1.0::IWifiIface
+ba5aa74f1ba714f0093864227923492808795bda6199c4ea0891322d27f8c931 android.hardware.wifi@1.0::IWifiNanIface
+325c94f3e1a565b56bbc74faddbd0ba7cb824f263dccf9dfff2daf62b86ed774 android.hardware.wifi@1.0::IWifiNanIfaceEventCallback
+c2c3f0372b41780fb6dfe83c022296806c2024d7046682fd201de5aa9b791c7a android.hardware.wifi@1.0::IWifiP2pIface
+766e9765f5c9c759b2a763c2288353fb5deff3389c2cc28f81d79c939704ce8b android.hardware.wifi@1.0::IWifiRttController
+72ab6f3e120cbf07aa6f8e87ca89112bdeb36b7fbb96bce5af3712323ab8b8e6 android.hardware.wifi@1.0::IWifiRttControllerEventCallback
+3b8093d39ef1e10e43c5538afbf5ff6e39b8d8168ebbe1998d993e89e25f14a5 android.hardware.wifi@1.0::IWifiStaIface
+7fbfc551c3e23c8b4398c3e16e452b516457e6921424a53474cbf373ca306fa9 android.hardware.wifi@1.0::IWifiStaIfaceEventCallback
+e20d5132d6d23e072c15de065b5e2aa13ff965031246a2c82581732bae56bf6d android.hardware.wifi@1.0::types
+f7e55c08187d8c855068a1ee3d0c8daeee7570292d96509c21a8756d4f5cfb9b android.hardware.wifi.supplicant@1.0::ISupplicant
+56b5c7267cb3d3337f44eb8b0b38ff4c6260dcc70e07687fcab94b1ccea8d159 android.hardware.wifi.supplicant@1.0::ISupplicantCallback
+35ba7bcdf18f24a866a7e5429548f06768bb20a257f75b10a397c4d825ef8438 android.hardware.wifi.supplicant@1.0::ISupplicantIface
+cda01008c06922fa37c1213e9bb831a109b3174532805616fb7161edc403866f android.hardware.wifi.supplicant@1.0::ISupplicantNetwork
+4907410338c5e8dbeec4b5edc2608ea323f5561945f8810af81810c47b019184 android.hardware.wifi.supplicant@1.0::ISupplicantP2pIface
+8b63f5efa2e3be3a7cb8a428760d82285a4ab79bcbdea6ef90aa547555e582d4 android.hardware.wifi.supplicant@1.0::ISupplicantP2pIfaceCallback
+56128f74560571b6777d59453f35c6b35693ee377e2a23c807708906928f09de android.hardware.wifi.supplicant@1.0::ISupplicantP2pNetwork
+2067c22197bca9743dab66a6f561a8a8375c67b4f76aed05f776839499bd4c8f android.hardware.wifi.supplicant@1.0::ISupplicantP2pNetworkCallback
+7752e1de93aaf5fed37011c219ac247069f6af320b0810daa98510584a10e7b4 android.hardware.wifi.supplicant@1.0::ISupplicantStaIface
+d781c8d7e7b3fe5cca8cf6e1d8806e770982ae5358c7816ed51b0f0ec272e70d android.hardware.wifi.supplicant@1.0::ISupplicantStaIfaceCallback
+b12ef0bdd8a4d247a8a6e960b227ed32383f2b0241f55d67fcea6eff6a6737fa android.hardware.wifi.supplicant@1.0::ISupplicantStaNetwork
+d8f0877ae1d321c1d884c7631dfe36cab0ec8a4b2863d4b687f85d3549a63bcc android.hardware.wifi.supplicant@1.0::ISupplicantStaNetworkCallback
+fe3c3c2f572b72f15f8594c538b0577bd5c28722c31879cfe6231330cddb6747 android.hardware.wifi.supplicant@1.0::types
+
+# ABI preserving changes to HALs released in Android O
+
+78589343d8ee2e1b155acad3fbdc7fcbb6af94491aee968b2383c21627264f8b android.hardware.radio@1.0::IRadioResponse
+c2c50ec74c87a583c683b4493f8f9f2e454a8d41c57af5b3eb88823a999f0ea4 android.hardware.radio@1.0::IRadioResponse
diff --git a/prebuilt_hashes/27.txt b/prebuilt_hashes/27.txt
new file mode 100644
index 0000000..23f2004
--- /dev/null
+++ b/prebuilt_hashes/27.txt
@@ -0,0 +1,249 @@
+# Do not change this file except to add new interfaces. Changing
+# pre-existing interfaces will fail VTS and break framework-only OTAs
+
+# HALs released in Android O
+
+f219c3b5b8c6cb1d659d4c7328f67246abfe1a8613f469826fd3b9ad090417a2 android.hardware.audio@2.0::IDevice
+4d579cae1cd87a783fd49233e10ce720ba183cfd1d5ccd80149e69de5c1c7362 android.hardware.audio@2.0::IDevicesFactory
+203e23f18011390b8cd10c303e0c16c4eebc8fa187e80e40d6be4624c2b0848a android.hardware.audio@2.0::IPrimaryDevice
+aaf93123deec336eb247ad8099849469a541ca0cf7c28c5f5336cebe1ee86748 android.hardware.audio@2.0::IStream
+0468c5723b0d44c5b451bdfa06153000c6f352fd3336e0ad2697127b04b766df android.hardware.audio@2.0::IStreamIn
+7296f7064fd3ab24082b43a1da34cc876268065310b785499fba5178d063680a android.hardware.audio@2.0::IStreamOut
+19d241d71c3e1140afba8140dcb57448446025a5fc03739788c4c25e9a98b6c2 android.hardware.audio@2.0::IStreamOutCallback
+c84da9f586087227daa3b96d42b4575326bccfd5bc8a2a5acf86d774f8ea2648 android.hardware.audio@2.0::types
+1305786c06e22b9b24ebde136054cc827b63c86d8bf4a136d6f7f54752b8566b android.hardware.audio.common@2.0::types
+fa8fbae3d1da3c264e4f3110728076abc09b4e65f12af6ae136367328de988ab android.hardware.audio.effect@2.0::IAcousticEchoCancelerEffect
+ca4752545d54547ff069eae161af7550cb5f5a7e8b60316ddd132a30906a68e7 android.hardware.audio.effect@2.0::IAutomaticGainControlEffect
+d2b8af988dc66f514d886bcee44b440d8034bc2a762f7161717ef3c956073067 android.hardware.audio.effect@2.0::IBassBoostEffect
+611bc09c75e796f3512b1ca6be508b0a9ba996759b8a2c60507784ff58076229 android.hardware.audio.effect@2.0::IDownmixEffect
+36a57369dfdc75180e8b64ae80b1970db8f6d9085dbff6ca931715038cc056e1 android.hardware.audio.effect@2.0::IEffect
+d2aa2df6d189c580f5be8460fa0ff4134d9c05a383f3204659baee426a6f0edf android.hardware.audio.effect@2.0::IEffectBufferProviderCallback
+217f9161983a48d3bf3faeb158f868aa8bf0ce25889e4ee3d2bab1a2e8d33e77 android.hardware.audio.effect@2.0::IEffectsFactory
+c2b38bc07991e880c83ca8cb88181411eeef708b8b936aedd2f2e0acade7df69 android.hardware.audio.effect@2.0::IEnvironmentalReverbEffect
+2ff9f9704be5f167745b4de790e9dafc3cc4719e2f6e2e5497085e679853cfe7 android.hardware.audio.effect@2.0::IEqualizerEffect
+c31447fb02dbc8b56c359941dad22f416511860173c5c5fd278d1bf2312b13de android.hardware.audio.effect@2.0::ILoudnessEnhancerEffect
+804831ca258802eb3eb65a0a7b5d5e3d37d4a15ba8c2836b4276eda98b47e1d0 android.hardware.audio.effect@2.0::INoiseSuppressionEffect
+778fd5b9837f481d8e47425b3e2a3bd0c6362a0b6870291518e2d863530fdb61 android.hardware.audio.effect@2.0::IPresetReverbEffect
+c93cb25a1a92d07aa80a617c01e8d22fc97bf8cefd3962b6a5be386ad4704d89 android.hardware.audio.effect@2.0::IVirtualizerEffect
+918f331780c9c7b04f2151a2e563aab088198ede8e6f865302ebaa13905bd9ce android.hardware.audio.effect@2.0::IVisualizerEffect
+4caad099f8fc00262b6c03ba41271808b37cea90ac98b534299bbf4ee823af02 android.hardware.audio.effect@2.0::types
+# android.hardware.automotive.* are unfrozen
+1fbdc1f852f8bd2e4a6c5cb30ac2b78668c98dce118a61762d4034ae859f43d8 android.hardware.biometrics.fingerprint@2.1::IBiometricsFingerprint
+aabb5c3c585592d71ee57b77298c14993d77914ddeaa64b2c5109a602b02ea47 android.hardware.biometrics.fingerprint@2.1::IBiometricsFingerprintClientCallback
+1ec60d4efddae9a7b2469278a576967b4751e88de5b8d7e9df6eff6bc0da7bc9 android.hardware.biometrics.fingerprint@2.1::types
+347ce746815607567f5f3b53e4800998ca5ab9355141f0880fc0cf0c1fc5c355 android.hardware.bluetooth@1.0::IBluetoothHci
+835f41be2281bfb22f3e33c6fa870bde7bc21e37e5cfbaf9a36fff170632f754 android.hardware.bluetooth@1.0::IBluetoothHciCallbacks
+a8dfd0dbe463a3cdbcf1d985b38a28b3d93ba2ae5a1d1db4aaef4c38a5781b91 android.hardware.bluetooth@1.0::types
+7192d756aeba00aba32f4504981df8172ffca83e210c4838dabf295e53e93590 android.hardware.boot@1.0::IBootControl
+cebaa803b8e33807a0d69f46652b650ccb549e8f9b19d6becbbf26690e828b49 android.hardware.boot@1.0::types
+a98d49f23712a7cc327d1e0602d05f6f3ad32cfb5c74711d009c726611ee1c93 android.hardware.broadcastradio@1.0::IBroadcastRadio
+ed82579c0c165feaa12d0e33c06b3342ab41ec0a439247f202775e8369e46ef6 android.hardware.broadcastradio@1.0::IBroadcastRadioFactory
+da6ab32ee2793d2c86d3b603075d5383852b89d7eaa201861aa0473d418f3c7f android.hardware.broadcastradio@1.0::ITuner
+04d3ca022e25c308d9efd2e7eb77b3a7a206907cdc1b9ea9326340b377868172 android.hardware.broadcastradio@1.0::ITunerCallback
+bd42c8d7838cfed1998b49c39745dec116d2d6edc2c11a4c0399b8f3a1d1655a android.hardware.broadcastradio@1.0::types
+81164323115d6588e259e8319fddf7487adfa1f49ce60f7e80ba74e0783392a4 android.hardware.camera.common@1.0::types
+c1705e9d62438a1d955269965af915ae28e692bd480a3b1ce67056fef992d62f android.hardware.camera.device@1.0::ICameraDevice
+78e9b44cf8660bdc1e98dca07451804153824efcd28db208a62f5ad728f44076 android.hardware.camera.device@1.0::ICameraDeviceCallback
+28f0386ba86ddf41e53a8117b48a0328d7a4d2574213e89f4a1062398a244566 android.hardware.camera.device@1.0::ICameraDevicePreviewCallback
+4db48439ce9dde97f1cfb3d7408f6c737f621ac0f7494aeea35ed599bc2352a3 android.hardware.camera.device@1.0::types
+b32f9aeaf1c442195eb06ffc7600968c919d005b2718874f09c57287fae55918 android.hardware.camera.device@3.2::ICameraDevice
+63bfc3da0f2d2301f7a0508c7c2b9ffc521d4d545ee03718da70e9d6273b3b21 android.hardware.camera.device@3.2::ICameraDeviceCallback
+0fa3e1e64819283b8737fc4e5ab759f0cb4ac1a996e8a51cc4aa8025a457208e android.hardware.camera.device@3.2::ICameraDeviceSession
+030be3d2b159cbde7920485807140f6b6064ef4a5de4a40a6c4bc8d2c72f7cd3 android.hardware.camera.device@3.2::types
+5ba7947cee515d7a2359bfcbfb9678c1c3a768c288471919ac095b96ae6f3d40 android.hardware.camera.metadata@3.2::types
+f7e299d85033ac52d1095a35784fcfeaff43603f58c751e4153c85bbade3b330 android.hardware.camera.provider@2.4::ICameraProvider
+a501ca1aecd09f1b9fd70a9af84205430dbd49a808e8fa395d363b9902e6f58c android.hardware.camera.provider@2.4::ICameraProviderCallback
+7f5fe8f4f8a24037153c504d8b4d3313c2ce33d81c8c69fe5194ddd2d4080e72 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
+87beacc481897cf02fb1628d75e68133de6d74d4cffe582cda2f5e16bdd74516 android.hardware.configstore@1.0::types
+a5ae0fe8667f0b1af09b13e72d29600f4eb3853b257079c45a99b6f4a3360649 android.hardware.contexthub@1.0::IContexthub
+2ab3054c2d9302d8417ee7495353a2887fe338f913276f2eb41e80f11395ec2e android.hardware.contexthub@1.0::IContexthubCallback
+c3b2b37d561d31ea094411f251bf73bea334f4fe849a4390aef5e20bca6cadba android.hardware.contexthub@1.0::types
+df174c1871c864b4c79ca9f64aae7936d24a272eca3191a30458ca2b706dec79 android.hardware.drm@1.0::ICryptoFactory
+83639e90caeb996b0274e420de3cd556779de1ca48464b68eee799bef32b34cd android.hardware.drm@1.0::ICryptoPlugin
+1440cffdfaeb12830ac10ee6ffdb0f1083e701057b806df11fb4787b4c91e718 android.hardware.drm@1.0::IDrmFactory
+78ba33b108f620e6a0eec01ef654547e69a85754578ea4c9ef03ec205f16121c android.hardware.drm@1.0::IDrmPlugin
+701d9e51952172364e4ea70db9c397f08c3b4577ba33051f050a6cdd532de1b4 android.hardware.drm@1.0::IDrmPluginListener
+4238d62ad90df63aa338c6f1b6264c09c5a3706945d5c49d1189c0be1dc9e942 android.hardware.drm@1.0::types
+f07b1ee3ba11a2fc9f200421b2e1afb7c1854ee987000e45c987fb9507795055 android.hardware.dumpstate@1.0::IDumpstateDevice
+c9d318df7922bde3b265927b521ff5a965002826fc0cabfcaef52a56760f2d34 android.hardware.gatekeeper@1.0::IGatekeeper
+da13bd69282fb275767abb18704c57ff8038e6c139ad17157dc702810f70d06a android.hardware.gatekeeper@1.0::types
+37c7da4f823ec958dfa9c960e2d341c48f877e0bfa758f3fa9e2d9c1e1bd66d9 android.hardware.gnss@1.0::IAGnss
+7ec9afdb964bfb8369866913caf018f2636592885bcb558a65de2c5436ab4f60 android.hardware.gnss@1.0::IAGnssCallback
+d16e6a359be6963ea753d7138e84ecf2b93052097938938c4d36d7a47ea2e2ae android.hardware.gnss@1.0::IAGnssRil
+2f907708d74d94b1e121ed27651c9c72af65952d347b58ff07dac5d5d7a7f678 android.hardware.gnss@1.0::IAGnssRilCallback
+5ac7edad06d76064b882be161f3f9d9692a997ec72e9f36addb7fe8918f49992 android.hardware.gnss@1.0::IGnss
+b05c983c87c3376e145223688c3b541b5e11b827f211e38d5a31af1ca3a2e222 android.hardware.gnss@1.0::IGnssBatching
+4981d2d2c4e725c7544be0956099a91fc7bbc8048c563394158083fe924e651e android.hardware.gnss@1.0::IGnssBatchingCallback
+3cd22d92cc1f935150c5048310e84886f14eed2556e8f00636733d204045cc4f android.hardware.gnss@1.0::IGnssCallback
+175185a5eda87476193ca5461df75dd16d36664591e8130530dd8ef0eb2ddf6a android.hardware.gnss@1.0::IGnssConfiguration
+4542122b96fbf27101cb8222bafb76e7c8d032d977dd1058edd8e5881ca5752f android.hardware.gnss@1.0::IGnssDebug
+e6dd0c8416e523ab9cbd14d56ab6f016481a8aef3bc8a750051122d31075f6c7 android.hardware.gnss@1.0::IGnssGeofenceCallback
+f90e4ddc652706299d8e3d8ba18e0745c3bae9bf4d1be6bd06d9c1f50ec8d28a android.hardware.gnss@1.0::IGnssGeofencing
+9ea8987bb1089c8c5d7b67866575b866ef516045021d9efcc37c6352bce072a3 android.hardware.gnss@1.0::IGnssMeasurement
+cf20492673d6a423e4c2e87fdfb5a4c4a602431721978db852e246f258e25edb android.hardware.gnss@1.0::IGnssMeasurementCallback
+af85aa0f48ae99a39f4688c344e4419304f681f9af818a5c8d759286fc4418de android.hardware.gnss@1.0::IGnssNavigationMessage
+76b0874ea4c06b29f66418c59820f4286b3be9629cd872923d0dfbb602cd432d android.hardware.gnss@1.0::IGnssNavigationMessageCallback
+248bcf51da4273d64f367bf6877baef2feeaca365459842fd3c214a2dc6e0224 android.hardware.gnss@1.0::IGnssNi
+c781b7b125f68be5db8a8c3d412d526acdbdf77dcc592a4c0ed70b8ce4fe6c49 android.hardware.gnss@1.0::IGnssNiCallback
+c1142657de16fdb292a502372fe938614d65270ab8359217d6e13604fe4dbca4 android.hardware.gnss@1.0::IGnssXtra
+bd366b83d8d565d0e8bfabff3adfcab0259d75b4e2a9f8e1b91e11d1593a2ffb android.hardware.gnss@1.0::IGnssXtraCallback
+881bc2f94026784d194cffbff166c6e8bf911de4e02abe96fc7d89ec75b0574a android.hardware.gnss@1.0::types
+17971eb8a482893dadcfc16e0583f492d42a034ef95d9b0b709417af30838396 android.hardware.graphics.allocator@2.0::IAllocator
+60bf42a4898e4fb70dbd720b263aeafd7f35f5e1a5effeabb4d5d659878a5f18 android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer
+b8a75617b9ec12bea641f3a73d4025a33e8b9a2f9169dd46094af56adf9249c5 android.hardware.graphics.bufferqueue@1.0::IProducerListener
+4f6dedbcdd21c309dfc650acea81a096d6b242493ffe49c8d61bd3c43aad354e android.hardware.graphics.common@1.0::types
+b3aac6c3817f039964fcd62268274b3039e17bd7d0d5b40b4d1d1c7b19a1f866 android.hardware.graphics.composer@2.1::IComposer
+b19d00eb8a8b3b0034a0321f22e8f32162bf4c2aebbce6da22c025f56e459ea2 android.hardware.graphics.composer@2.1::IComposerCallback
+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
+91e2ba3805c923f01fc1231ec9ff838942aee3346f2d7614ecc0caeadbe57ed4 android.hardware.health@1.0::IHealth
+1275aa2e8732909101b26aec49ed2285489e89d97b8610a8908b7868e35a3cc5 android.hardware.health@1.0::types
+3a8d3922e06e6d4f8e0befc6be78d0e9e07aed1585b3da6521bed406d25a9483 android.hardware.ir@1.0::IConsumerIr
+7090bd37912fcf723a12f4bc17783e3527577c4944805a028c296fd7a95bd682 android.hardware.ir@1.0::types
+cc7925a78c0ab022515f48840d3dae76f384ed3a1287abadcb461a5cd5396163 android.hardware.keymaster@3.0::IKeymasterDevice
+822998d7bb76f0cd719a409291434fcb56e6d50bc4780788bb157a3374d63b8c android.hardware.keymaster@3.0::types
+d4ed2f0e14f9e914d0b1275d2e0363192fe30aca9059c84edb5fad15995f9ec4 android.hardware.light@2.0::ILight
+d9584bfcaedd6e62cf337881748246b23e36cbc2bc3aa84c01b6a1e622061400 android.hardware.light@2.0::types
+16c0cf0f73de1e5208a95020c6c6474903e7094f76b2d782651afaca0e5fd86f android.hardware.media@1.0::types
+8bc2f5fdcad68856eb61a62fe4cc043fa064bb7f1dab95a71d1918ec1eef7b55 android.hardware.media.omx@1.0::IGraphicBufferSource
+0d3de9cd89d4718ea3b772f2d8b93be004feb3abb7e7dc5402e37047cc730d05 android.hardware.media.omx@1.0::IOmx
+32002e1c358c64de106c977a6dc6af7da27be4803a5bb66fd6f891a5ba0a1617 android.hardware.media.omx@1.0::IOmxBufferSource
+81ad8d8bb1cf6f41923cf11dd39354a8fe433db284a234cc675de7e75a82224c android.hardware.media.omx@1.0::IOmxNode
+494c0c8bf6065edc82ec127228ed19dd2243dc1c2f7d601c7c6be7b7015c1713 android.hardware.media.omx@1.0::IOmxObserver
+252c2fc50c78fd6de8365e5b60e5115119ace107db0b94b0b26815cbf3d2b64a android.hardware.media.omx@1.0::IOmxStore
+148c1b50b0958988373145ffdf5fa0e1b6534e0a2034a570e74b15c127cf7c5e android.hardware.media.omx@1.0::types
+c66902fe48d687ac6740a3e32ae55fb75532c48c36c6386461c2b4416ad2e0f1 android.hardware.memtrack@1.0::IMemtrack
+860bacd8b11a269c40567542b613fe4ca448d5cb4326d0058899e608e89dfca1 android.hardware.memtrack@1.0::types
+07ac2dc95270321ec7d4c33cd25e5085a057f47fe350d645af6f7a7a11e3cf57 android.hardware.nfc@1.0::INfc
+f2fe54426c07d67388d4774a60641ad4c0538f22eb6e1111722f231772655de6 android.hardware.nfc@1.0::INfcClientCallback
+9626fd18db113d709faf593a70caf19bd0980294d23c468c80c30186f9d298a6 android.hardware.nfc@1.0::types
+deee1dc4948f33af207e1008aba0f6cc07afb7900eab53f33192c8cac137eefc android.hardware.power@1.0::IPower
+efc83df3f962b93c7c0290d691d7d300dabe12683e2cde3591fb3c0beedce20f android.hardware.power@1.0::types
+9b5aa499ec3b4226f15f48f5ed08896e2fc0676f978c9e199c1da21daaf002a6 android.hardware.radio@1.0::IRadio
+5c8efbb9c451a59737ed2c6c20230aae4745839ca01d8088d6dcc9020e52d2c5 android.hardware.radio@1.0::IRadioIndication
+69f6b4b8ec40ca02ccc7bb8227a097135c20c00bd94c822e421cd9af1267252c android.hardware.radio@1.0::IRadioResponse
+de3ab9f73b1073cd677b19d886fb927e9381b30161a704712d2b30f875873f5c android.hardware.radio@1.0::ISap
+d183e406ef0897df2117a9dde384e8e6ea4fa6ab1c7f6f28e65b87011218c9ea android.hardware.radio@1.0::ISapCallback
+96986fbd22f0e6ca752e1fcdc0a64bda213995a81f5f36bc4faf3532d9306b97 android.hardware.radio@1.0::types
+00f70085d6fae1d482fb700a3fd42ed475384c95b51c9269b9ae5037b74ad4dd android.hardware.radio.deprecated@1.0::IOemHook
+06837b6d7e843cfa9cd20fed4070feca7a9b5c81a9ed643bf7d06803455a9816 android.hardware.radio.deprecated@1.0::IOemHookIndication
+6fd4874f0eddd4626a27658fd94fad526c317f3563439e79718bdb1a3a2309d5 android.hardware.radio.deprecated@1.0::IOemHookResponse
+6983a2cafe39d5c57dfdc1743055fb0f757a0df8c78e00423d5e1810836927e1 android.hardware.renderscript@1.0::IContext
+7f9417a0ccf78ea042ec7a8ac8e3750346d4d9d7e5ae01b1b35fde303f47c24d android.hardware.renderscript@1.0::IDevice
+fc6f325b266b32353f7d1534fbe58e0d368265a12b77fa396fb556e8c443f739 android.hardware.renderscript@1.0::types
+89585ff541c319de4091a5a0b687dd526ac81c6382ffd7b979a4164b3d7419a6 android.hardware.sensors@1.0::ISensors
+e04ab978fc28f4c515f4a75617dfda8607733a64f13666beeb0e604a07a39333 android.hardware.sensors@1.0::types
+5befc019cbe94953661e2cdb95e3cf64f5e565c29403e1c2daecc2be44e0a55c android.hardware.soundtrigger@2.0::ISoundTriggerHw
+d7ec5f612a5e0a59ea4f2b61317e208ff56dd50920fd4eb441e0cbc8f97e4f49 android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
+5bee9e70f7e5ec7ee252883b28f98f12b59960f4c2a0b4cc9a4526e4669ebcd4 android.hardware.soundtrigger@2.0::types
+97f1ec446043bc5a6645b74529a6276496bdb35e0aee41eda55cb92d51eb7802 android.hardware.thermal@1.0::IThermal
+84965a6908bceb4ef51546bf8731f309f1ea9d09a0177dcc7974132e523dd6d2 android.hardware.thermal@1.0::types
+938850621c3c5ef426a4b88e752ba99b3559037e782a3d938604f3aef5cc0f1b android.hardware.tv.cec@1.0::IHdmiCec
+e75b6eea711d36fac678bce072b3cec6544b27fa9f4cd903999404e5c110ca10 android.hardware.tv.cec@1.0::IHdmiCecCallback
+6e25f8dbfadb668e1d4ec80eb9acd95d8bc9e0a240c36d27e662adb440314b95 android.hardware.tv.cec@1.0::types
+0cafa3c8388e9631916d2d800f78decbcec2904f11415b32c71a31d9a51ebf79 android.hardware.tv.input@1.0::ITvInput
+dee83e5c864fbbee8f02448d0800be32f06856386b9f907bc5d952208c9434f9 android.hardware.tv.input@1.0::ITvInputCallback
+07aab30410b612381234dca6d453d4ab96f2e536368715717c6e28101b9851b5 android.hardware.tv.input@1.0::types
+4ef57499273f38bdbdd0c15e56ee7a4bc5f18a5644092170a531df3541d9e015 android.hardware.usb@1.0::IUsb
+4be7881e411ba42784bf5b7354c14ae0cf161004d39433aaecaab0d19ea99354 android.hardware.usb@1.0::IUsbCallback
+f7e6e747910a3cd0a35846141e3b990a6a612a297b2b70ccd5740b646a450a8c android.hardware.usb@1.0::types
+06ea64cc3565777f3b259e400ffa7100d07f3827ad9357b0c5d3c651384e5553 android.hardware.vibrator@1.0::IVibrator
+0fecd34ae64f32eff6aa615fd662349242c0b8b6e303ef05a7cb5776c732f413 android.hardware.vibrator@1.0::types
+4b962968a7df4ab104d1315d66a0a7348a713fecbb5d2c1b23688494458f37ce android.hardware.vr@1.0::IVr
+b9be36719a8ad534000a51ea07be91be94c405bf1e038ae825acf65087ffd378 android.hardware.wifi@1.0::IWifi
+ee0224ee18813506d9d6f13d8c8e4679f053c290a443a52a7c52a5d3c852262b android.hardware.wifi@1.0::IWifiApIface
+f3eecc489deb4c74892f59eb7adb769063bd5c354ac132b626a5f42b363d36bc android.hardware.wifi@1.0::IWifiChip
+a1b988377645a58e5e2542ca2bad4e17c21a4a389213d05de2f0e32d57b7d339 android.hardware.wifi@1.0::IWifiChipEventCallback
+5ed6760ce77e84bc6c49d1acb3f7d8117c9176b3f06514bc44ad3af84c80dcfe android.hardware.wifi@1.0::IWifiEventCallback
+6b9ad43a5efbe6ca214f751e22ce43cf5cd4d5d5f2cba80f24ccd3755a72401c android.hardware.wifi@1.0::IWifiIface
+ba5aa74f1ba714f0093864227923492808795bda6199c4ea0891322d27f8c931 android.hardware.wifi@1.0::IWifiNanIface
+325c94f3e1a565b56bbc74faddbd0ba7cb824f263dccf9dfff2daf62b86ed774 android.hardware.wifi@1.0::IWifiNanIfaceEventCallback
+c2c3f0372b41780fb6dfe83c022296806c2024d7046682fd201de5aa9b791c7a android.hardware.wifi@1.0::IWifiP2pIface
+766e9765f5c9c759b2a763c2288353fb5deff3389c2cc28f81d79c939704ce8b android.hardware.wifi@1.0::IWifiRttController
+72ab6f3e120cbf07aa6f8e87ca89112bdeb36b7fbb96bce5af3712323ab8b8e6 android.hardware.wifi@1.0::IWifiRttControllerEventCallback
+3b8093d39ef1e10e43c5538afbf5ff6e39b8d8168ebbe1998d993e89e25f14a5 android.hardware.wifi@1.0::IWifiStaIface
+7fbfc551c3e23c8b4398c3e16e452b516457e6921424a53474cbf373ca306fa9 android.hardware.wifi@1.0::IWifiStaIfaceEventCallback
+e20d5132d6d23e072c15de065b5e2aa13ff965031246a2c82581732bae56bf6d android.hardware.wifi@1.0::types
+f7e55c08187d8c855068a1ee3d0c8daeee7570292d96509c21a8756d4f5cfb9b android.hardware.wifi.supplicant@1.0::ISupplicant
+56b5c7267cb3d3337f44eb8b0b38ff4c6260dcc70e07687fcab94b1ccea8d159 android.hardware.wifi.supplicant@1.0::ISupplicantCallback
+35ba7bcdf18f24a866a7e5429548f06768bb20a257f75b10a397c4d825ef8438 android.hardware.wifi.supplicant@1.0::ISupplicantIface
+cda01008c06922fa37c1213e9bb831a109b3174532805616fb7161edc403866f android.hardware.wifi.supplicant@1.0::ISupplicantNetwork
+4907410338c5e8dbeec4b5edc2608ea323f5561945f8810af81810c47b019184 android.hardware.wifi.supplicant@1.0::ISupplicantP2pIface
+8b63f5efa2e3be3a7cb8a428760d82285a4ab79bcbdea6ef90aa547555e582d4 android.hardware.wifi.supplicant@1.0::ISupplicantP2pIfaceCallback
+56128f74560571b6777d59453f35c6b35693ee377e2a23c807708906928f09de android.hardware.wifi.supplicant@1.0::ISupplicantP2pNetwork
+2067c22197bca9743dab66a6f561a8a8375c67b4f76aed05f776839499bd4c8f android.hardware.wifi.supplicant@1.0::ISupplicantP2pNetworkCallback
+7752e1de93aaf5fed37011c219ac247069f6af320b0810daa98510584a10e7b4 android.hardware.wifi.supplicant@1.0::ISupplicantStaIface
+d781c8d7e7b3fe5cca8cf6e1d8806e770982ae5358c7816ed51b0f0ec272e70d android.hardware.wifi.supplicant@1.0::ISupplicantStaIfaceCallback
+b12ef0bdd8a4d247a8a6e960b227ed32383f2b0241f55d67fcea6eff6a6737fa android.hardware.wifi.supplicant@1.0::ISupplicantStaNetwork
+d8f0877ae1d321c1d884c7631dfe36cab0ec8a4b2863d4b687f85d3549a63bcc android.hardware.wifi.supplicant@1.0::ISupplicantStaNetworkCallback
+fe3c3c2f572b72f15f8594c538b0577bd5c28722c31879cfe6231330cddb6747 android.hardware.wifi.supplicant@1.0::types
+
+# ABI preserving changes to HALs during Android O MR1 (Initial Set)
+
+# android.hardware.automotive.* are unfrozen
+150a338ce11fcec70757c9675d83cf6a5d7b40d0c812741b91671fecce59eac9 android.hardware.broadcastradio@1.0::types
+dc7e6d4f537b9943e27edc4f86c5a03bb643b18f18f866f8c3c71c0ac4ea8cbc android.hardware.broadcastradio@1.0::types
+760485232f6cce07f8bb05e3475509956996b702f77415ee5bff05e2ec5a5bcc android.hardware.dumpstate@1.0::IDumpstateDevice
+e822cb7f4a1bdd45689c5e92ccd19a2201c20b771bd4b2ec1ae627e324591f9d android.hardware.radio@1.0::IRadioResponse
+6e69adb24d7c0b0ca3a54a38c49a5625b161b3f5d5f7d6fda0befdbbfc8e9e06 android.hardware.radio@1.0::IRadioResponse
+28e929b453df3d9f5060af2764e6cdb123ddb893e3e86923c877f6ff7e5f02c9 android.hardware.wifi@1.0::types
+df1d7b27e644bfed0a4f606a8c44d35d45cafce82c7c648494c8a25c7cd4a949 android.hardware.wifi@1.0::types
+
+# HALs released in Android O MR1 (Initial Set)
+
+4b65763663a94a3920134011691f8fbb42ccb7b7795589efddc049a9106047d6 android.hardware.oemlock@1.0::IOemLock
+e02cd3722cb5e8fa51179f5defacb4f7866f903c9c7c51dc01a3148473a71525 android.hardware.oemlock@1.0::types
+224f9d22a367a0016f09b6dc676f53f1446697d9dc747163032329e5da552de5 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
+b056e1defab4071584214584057d0bc73a613081bf1152590549649d4582c13c android.hardware.wifi@1.1::IWifiChip
+
+# ABI preserving changes to HALs during Android O MR1 (Final Set)
+2d833aeed0cd1d59437aca210be590a953cf32bcb6683cd63d089762a643fb49 android.hardware.radio@1.0::IRadioResponse
+05aa3de6130a9788fdb6f4d3cc57c3ea90f067e77a5e09d6a772ec7f6bca33d2 android.hardware.radio@1.1::IRadioResponse
+
+# HALs released in Android O MR1 (Final Set)
+044cb039378b8a0e36f40ff1e6ce04dc0d339da02095f968d5062a051e99d108 android.hardware.broadcastradio@1.1::types
+c9699483f8cefe4f9b39b4b9609b76cab2dd1659a06188056b45797d337d4256 android.hardware.broadcastradio@1.1::IBroadcastRadio
+b5d62dcd663fc4fcc977b252af59b333043bdfe73de2f11fe6d6a8bf438a0f92 android.hardware.broadcastradio@1.1::IBroadcastRadioFactory
+bc7e054a6e93adebedff345aeed44549be89e6b1b6ffe071ff47a61de764b232 android.hardware.broadcastradio@1.1::ITuner
+e9139fc755be578693f17c8cd1e27c75f412cfc722157bab5bf03ee68896e31d android.hardware.broadcastradio@1.1::ITunerCallback
+63929c99e5755d9e09d9e0fd2527391fbb1609dda0508f5933b7943b92ae0fbc android.hardware.camera.device@3.3::types
+bbcfc3f748b078f6a66c4e228084a679d30bd61bfde8bb7a91efd507b91c1bfd android.hardware.camera.device@3.3::ICameraDeviceSession
+4a6998cd6793a3f9f03989c29d662589b1bc9d38826c6698c6c17864f7a814f5 android.hardware.cas@1.0::types
+0e656ba1bac11461a17096ef752b69d24b000d820ef5652f0150a0f9731d54c2 android.hardware.cas@1.0::ICas
+b80e1456b81f80032d0de7cb45652ac15af11e7474d520d757481ecaad796dff android.hardware.cas@1.0::ICasListener
+a432d6d9200248dc2126827bcd6cdea31dd65eff39b939f64585d27d915a5857 android.hardware.cas@1.0::IDescramblerBase
+86ba9c03978b79a742e990420bc5ced0673d25a939f82572996bef92621e2014 android.hardware.cas@1.0::IMediaCasService
+503da837d1a67cbdb7c08a033e927e5430ae1b159d98bf72c6336b4dcc5e76f5 android.hardware.cas.native@1.0::types
+619600109232ed64b827c8a11beed8070b1827ae464547d7aa146cf0473b4bca android.hardware.cas.native@1.0::IDescrambler
+0a159f81359cd4f71bbe00972ee8403ea79351fb7c0cd48be72ebb3e424dbaef android.hardware.radio@1.0::types
+09342041e17c429fce0034b9096d17849122111436a5f0053e7e59500e1cb89c android.hardware.media.omx@1.0::IOmxStore
+246a56d37d57a47224562c9d077b4a2886ce6242b9311bd98a17325944c280d7 android.hardware.neuralnetworks@1.0::types
+93eb3757ceaf21590fa4cd1d4a7dfe3b3794af5396100a6d25630879352abce9 android.hardware.neuralnetworks@1.0::IDevice
+f66f9a38541bf92001d3adcce678cd7e3da2262124befb460b1c9aea9492813b android.hardware.neuralnetworks@1.0::IExecutionCallback
+953607822954435874f4b81686440a604e2a88cdd2d9164c6293f3d5772510d7 android.hardware.neuralnetworks@1.0::IPreparedModel
+73e03573494ba96f0e711ab7f1956c5b2d54c3da690cd7ecf4d6d0f287447730 android.hardware.neuralnetworks@1.0::IPreparedModelCallback
+f4945e397b5dea41bb64518dfde59be71245d8a125fd1e0acffeb57ac7b08fed android.hardware.thermal@1.1::IThermal
+c8bc853546dd55584611def2a9fa1d99f657e3366c976d2f60fe6b8aa6d2cb87 android.hardware.thermal@1.1::IThermalCallback
diff --git a/prebuilt_hashes/28.txt b/prebuilt_hashes/28.txt
new file mode 100644
index 0000000..cc15322
--- /dev/null
+++ b/prebuilt_hashes/28.txt
@@ -0,0 +1,382 @@
+# Do not change this file except to add new interfaces. Changing
+# pre-existing interfaces will fail VTS and break framework-only OTAs
+
+# HALs released in Android O
+
+f219c3b5b8c6cb1d659d4c7328f67246abfe1a8613f469826fd3b9ad090417a2 android.hardware.audio@2.0::IDevice
+4d579cae1cd87a783fd49233e10ce720ba183cfd1d5ccd80149e69de5c1c7362 android.hardware.audio@2.0::IDevicesFactory
+203e23f18011390b8cd10c303e0c16c4eebc8fa187e80e40d6be4624c2b0848a android.hardware.audio@2.0::IPrimaryDevice
+aaf93123deec336eb247ad8099849469a541ca0cf7c28c5f5336cebe1ee86748 android.hardware.audio@2.0::IStream
+0468c5723b0d44c5b451bdfa06153000c6f352fd3336e0ad2697127b04b766df android.hardware.audio@2.0::IStreamIn
+7296f7064fd3ab24082b43a1da34cc876268065310b785499fba5178d063680a android.hardware.audio@2.0::IStreamOut
+19d241d71c3e1140afba8140dcb57448446025a5fc03739788c4c25e9a98b6c2 android.hardware.audio@2.0::IStreamOutCallback
+c84da9f586087227daa3b96d42b4575326bccfd5bc8a2a5acf86d774f8ea2648 android.hardware.audio@2.0::types
+1305786c06e22b9b24ebde136054cc827b63c86d8bf4a136d6f7f54752b8566b android.hardware.audio.common@2.0::types
+fa8fbae3d1da3c264e4f3110728076abc09b4e65f12af6ae136367328de988ab android.hardware.audio.effect@2.0::IAcousticEchoCancelerEffect
+ca4752545d54547ff069eae161af7550cb5f5a7e8b60316ddd132a30906a68e7 android.hardware.audio.effect@2.0::IAutomaticGainControlEffect
+d2b8af988dc66f514d886bcee44b440d8034bc2a762f7161717ef3c956073067 android.hardware.audio.effect@2.0::IBassBoostEffect
+611bc09c75e796f3512b1ca6be508b0a9ba996759b8a2c60507784ff58076229 android.hardware.audio.effect@2.0::IDownmixEffect
+36a57369dfdc75180e8b64ae80b1970db8f6d9085dbff6ca931715038cc056e1 android.hardware.audio.effect@2.0::IEffect
+d2aa2df6d189c580f5be8460fa0ff4134d9c05a383f3204659baee426a6f0edf android.hardware.audio.effect@2.0::IEffectBufferProviderCallback
+217f9161983a48d3bf3faeb158f868aa8bf0ce25889e4ee3d2bab1a2e8d33e77 android.hardware.audio.effect@2.0::IEffectsFactory
+c2b38bc07991e880c83ca8cb88181411eeef708b8b936aedd2f2e0acade7df69 android.hardware.audio.effect@2.0::IEnvironmentalReverbEffect
+2ff9f9704be5f167745b4de790e9dafc3cc4719e2f6e2e5497085e679853cfe7 android.hardware.audio.effect@2.0::IEqualizerEffect
+c31447fb02dbc8b56c359941dad22f416511860173c5c5fd278d1bf2312b13de android.hardware.audio.effect@2.0::ILoudnessEnhancerEffect
+804831ca258802eb3eb65a0a7b5d5e3d37d4a15ba8c2836b4276eda98b47e1d0 android.hardware.audio.effect@2.0::INoiseSuppressionEffect
+778fd5b9837f481d8e47425b3e2a3bd0c6362a0b6870291518e2d863530fdb61 android.hardware.audio.effect@2.0::IPresetReverbEffect
+c93cb25a1a92d07aa80a617c01e8d22fc97bf8cefd3962b6a5be386ad4704d89 android.hardware.audio.effect@2.0::IVirtualizerEffect
+918f331780c9c7b04f2151a2e563aab088198ede8e6f865302ebaa13905bd9ce android.hardware.audio.effect@2.0::IVisualizerEffect
+4caad099f8fc00262b6c03ba41271808b37cea90ac98b534299bbf4ee823af02 android.hardware.audio.effect@2.0::types
+1fbdc1f852f8bd2e4a6c5cb30ac2b78668c98dce118a61762d4034ae859f43d8 android.hardware.biometrics.fingerprint@2.1::IBiometricsFingerprint
+aabb5c3c585592d71ee57b77298c14993d77914ddeaa64b2c5109a602b02ea47 android.hardware.biometrics.fingerprint@2.1::IBiometricsFingerprintClientCallback
+1ec60d4efddae9a7b2469278a576967b4751e88de5b8d7e9df6eff6bc0da7bc9 android.hardware.biometrics.fingerprint@2.1::types
+347ce746815607567f5f3b53e4800998ca5ab9355141f0880fc0cf0c1fc5c355 android.hardware.bluetooth@1.0::IBluetoothHci
+835f41be2281bfb22f3e33c6fa870bde7bc21e37e5cfbaf9a36fff170632f754 android.hardware.bluetooth@1.0::IBluetoothHciCallbacks
+a8dfd0dbe463a3cdbcf1d985b38a28b3d93ba2ae5a1d1db4aaef4c38a5781b91 android.hardware.bluetooth@1.0::types
+7192d756aeba00aba32f4504981df8172ffca83e210c4838dabf295e53e93590 android.hardware.boot@1.0::IBootControl
+cebaa803b8e33807a0d69f46652b650ccb549e8f9b19d6becbbf26690e828b49 android.hardware.boot@1.0::types
+a98d49f23712a7cc327d1e0602d05f6f3ad32cfb5c74711d009c726611ee1c93 android.hardware.broadcastradio@1.0::IBroadcastRadio
+ed82579c0c165feaa12d0e33c06b3342ab41ec0a439247f202775e8369e46ef6 android.hardware.broadcastradio@1.0::IBroadcastRadioFactory
+da6ab32ee2793d2c86d3b603075d5383852b89d7eaa201861aa0473d418f3c7f android.hardware.broadcastradio@1.0::ITuner
+04d3ca022e25c308d9efd2e7eb77b3a7a206907cdc1b9ea9326340b377868172 android.hardware.broadcastradio@1.0::ITunerCallback
+bd42c8d7838cfed1998b49c39745dec116d2d6edc2c11a4c0399b8f3a1d1655a android.hardware.broadcastradio@1.0::types
+81164323115d6588e259e8319fddf7487adfa1f49ce60f7e80ba74e0783392a4 android.hardware.camera.common@1.0::types
+c1705e9d62438a1d955269965af915ae28e692bd480a3b1ce67056fef992d62f android.hardware.camera.device@1.0::ICameraDevice
+78e9b44cf8660bdc1e98dca07451804153824efcd28db208a62f5ad728f44076 android.hardware.camera.device@1.0::ICameraDeviceCallback
+28f0386ba86ddf41e53a8117b48a0328d7a4d2574213e89f4a1062398a244566 android.hardware.camera.device@1.0::ICameraDevicePreviewCallback
+4db48439ce9dde97f1cfb3d7408f6c737f621ac0f7494aeea35ed599bc2352a3 android.hardware.camera.device@1.0::types
+b32f9aeaf1c442195eb06ffc7600968c919d005b2718874f09c57287fae55918 android.hardware.camera.device@3.2::ICameraDevice
+63bfc3da0f2d2301f7a0508c7c2b9ffc521d4d545ee03718da70e9d6273b3b21 android.hardware.camera.device@3.2::ICameraDeviceCallback
+0fa3e1e64819283b8737fc4e5ab759f0cb4ac1a996e8a51cc4aa8025a457208e android.hardware.camera.device@3.2::ICameraDeviceSession
+030be3d2b159cbde7920485807140f6b6064ef4a5de4a40a6c4bc8d2c72f7cd3 android.hardware.camera.device@3.2::types
+5ba7947cee515d7a2359bfcbfb9678c1c3a768c288471919ac095b96ae6f3d40 android.hardware.camera.metadata@3.2::types
+f7e299d85033ac52d1095a35784fcfeaff43603f58c751e4153c85bbade3b330 android.hardware.camera.provider@2.4::ICameraProvider
+a501ca1aecd09f1b9fd70a9af84205430dbd49a808e8fa395d363b9902e6f58c android.hardware.camera.provider@2.4::ICameraProviderCallback
+7f5fe8f4f8a24037153c504d8b4d3313c2ce33d81c8c69fe5194ddd2d4080e72 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
+87beacc481897cf02fb1628d75e68133de6d74d4cffe582cda2f5e16bdd74516 android.hardware.configstore@1.0::types
+a5ae0fe8667f0b1af09b13e72d29600f4eb3853b257079c45a99b6f4a3360649 android.hardware.contexthub@1.0::IContexthub
+2ab3054c2d9302d8417ee7495353a2887fe338f913276f2eb41e80f11395ec2e android.hardware.contexthub@1.0::IContexthubCallback
+c3b2b37d561d31ea094411f251bf73bea334f4fe849a4390aef5e20bca6cadba android.hardware.contexthub@1.0::types
+df174c1871c864b4c79ca9f64aae7936d24a272eca3191a30458ca2b706dec79 android.hardware.drm@1.0::ICryptoFactory
+83639e90caeb996b0274e420de3cd556779de1ca48464b68eee799bef32b34cd android.hardware.drm@1.0::ICryptoPlugin
+1440cffdfaeb12830ac10ee6ffdb0f1083e701057b806df11fb4787b4c91e718 android.hardware.drm@1.0::IDrmFactory
+78ba33b108f620e6a0eec01ef654547e69a85754578ea4c9ef03ec205f16121c android.hardware.drm@1.0::IDrmPlugin
+701d9e51952172364e4ea70db9c397f08c3b4577ba33051f050a6cdd532de1b4 android.hardware.drm@1.0::IDrmPluginListener
+4238d62ad90df63aa338c6f1b6264c09c5a3706945d5c49d1189c0be1dc9e942 android.hardware.drm@1.0::types
+f07b1ee3ba11a2fc9f200421b2e1afb7c1854ee987000e45c987fb9507795055 android.hardware.dumpstate@1.0::IDumpstateDevice
+c9d318df7922bde3b265927b521ff5a965002826fc0cabfcaef52a56760f2d34 android.hardware.gatekeeper@1.0::IGatekeeper
+da13bd69282fb275767abb18704c57ff8038e6c139ad17157dc702810f70d06a android.hardware.gatekeeper@1.0::types
+37c7da4f823ec958dfa9c960e2d341c48f877e0bfa758f3fa9e2d9c1e1bd66d9 android.hardware.gnss@1.0::IAGnss
+7ec9afdb964bfb8369866913caf018f2636592885bcb558a65de2c5436ab4f60 android.hardware.gnss@1.0::IAGnssCallback
+d16e6a359be6963ea753d7138e84ecf2b93052097938938c4d36d7a47ea2e2ae android.hardware.gnss@1.0::IAGnssRil
+2f907708d74d94b1e121ed27651c9c72af65952d347b58ff07dac5d5d7a7f678 android.hardware.gnss@1.0::IAGnssRilCallback
+5ac7edad06d76064b882be161f3f9d9692a997ec72e9f36addb7fe8918f49992 android.hardware.gnss@1.0::IGnss
+b05c983c87c3376e145223688c3b541b5e11b827f211e38d5a31af1ca3a2e222 android.hardware.gnss@1.0::IGnssBatching
+4981d2d2c4e725c7544be0956099a91fc7bbc8048c563394158083fe924e651e android.hardware.gnss@1.0::IGnssBatchingCallback
+3cd22d92cc1f935150c5048310e84886f14eed2556e8f00636733d204045cc4f android.hardware.gnss@1.0::IGnssCallback
+175185a5eda87476193ca5461df75dd16d36664591e8130530dd8ef0eb2ddf6a android.hardware.gnss@1.0::IGnssConfiguration
+4542122b96fbf27101cb8222bafb76e7c8d032d977dd1058edd8e5881ca5752f android.hardware.gnss@1.0::IGnssDebug
+e6dd0c8416e523ab9cbd14d56ab6f016481a8aef3bc8a750051122d31075f6c7 android.hardware.gnss@1.0::IGnssGeofenceCallback
+f90e4ddc652706299d8e3d8ba18e0745c3bae9bf4d1be6bd06d9c1f50ec8d28a android.hardware.gnss@1.0::IGnssGeofencing
+9ea8987bb1089c8c5d7b67866575b866ef516045021d9efcc37c6352bce072a3 android.hardware.gnss@1.0::IGnssMeasurement
+cf20492673d6a423e4c2e87fdfb5a4c4a602431721978db852e246f258e25edb android.hardware.gnss@1.0::IGnssMeasurementCallback
+af85aa0f48ae99a39f4688c344e4419304f681f9af818a5c8d759286fc4418de android.hardware.gnss@1.0::IGnssNavigationMessage
+76b0874ea4c06b29f66418c59820f4286b3be9629cd872923d0dfbb602cd432d android.hardware.gnss@1.0::IGnssNavigationMessageCallback
+248bcf51da4273d64f367bf6877baef2feeaca365459842fd3c214a2dc6e0224 android.hardware.gnss@1.0::IGnssNi
+c781b7b125f68be5db8a8c3d412d526acdbdf77dcc592a4c0ed70b8ce4fe6c49 android.hardware.gnss@1.0::IGnssNiCallback
+c1142657de16fdb292a502372fe938614d65270ab8359217d6e13604fe4dbca4 android.hardware.gnss@1.0::IGnssXtra
+bd366b83d8d565d0e8bfabff3adfcab0259d75b4e2a9f8e1b91e11d1593a2ffb android.hardware.gnss@1.0::IGnssXtraCallback
+881bc2f94026784d194cffbff166c6e8bf911de4e02abe96fc7d89ec75b0574a android.hardware.gnss@1.0::types
+17971eb8a482893dadcfc16e0583f492d42a034ef95d9b0b709417af30838396 android.hardware.graphics.allocator@2.0::IAllocator
+60bf42a4898e4fb70dbd720b263aeafd7f35f5e1a5effeabb4d5d659878a5f18 android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer
+b8a75617b9ec12bea641f3a73d4025a33e8b9a2f9169dd46094af56adf9249c5 android.hardware.graphics.bufferqueue@1.0::IProducerListener
+4f6dedbcdd21c309dfc650acea81a096d6b242493ffe49c8d61bd3c43aad354e android.hardware.graphics.common@1.0::types
+b3aac6c3817f039964fcd62268274b3039e17bd7d0d5b40b4d1d1c7b19a1f866 android.hardware.graphics.composer@2.1::IComposer
+b19d00eb8a8b3b0034a0321f22e8f32162bf4c2aebbce6da22c025f56e459ea2 android.hardware.graphics.composer@2.1::IComposerCallback
+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
+91e2ba3805c923f01fc1231ec9ff838942aee3346f2d7614ecc0caeadbe57ed4 android.hardware.health@1.0::IHealth
+1275aa2e8732909101b26aec49ed2285489e89d97b8610a8908b7868e35a3cc5 android.hardware.health@1.0::types
+3a8d3922e06e6d4f8e0befc6be78d0e9e07aed1585b3da6521bed406d25a9483 android.hardware.ir@1.0::IConsumerIr
+7090bd37912fcf723a12f4bc17783e3527577c4944805a028c296fd7a95bd682 android.hardware.ir@1.0::types
+cc7925a78c0ab022515f48840d3dae76f384ed3a1287abadcb461a5cd5396163 android.hardware.keymaster@3.0::IKeymasterDevice
+822998d7bb76f0cd719a409291434fcb56e6d50bc4780788bb157a3374d63b8c android.hardware.keymaster@3.0::types
+d4ed2f0e14f9e914d0b1275d2e0363192fe30aca9059c84edb5fad15995f9ec4 android.hardware.light@2.0::ILight
+d9584bfcaedd6e62cf337881748246b23e36cbc2bc3aa84c01b6a1e622061400 android.hardware.light@2.0::types
+16c0cf0f73de1e5208a95020c6c6474903e7094f76b2d782651afaca0e5fd86f android.hardware.media@1.0::types
+8bc2f5fdcad68856eb61a62fe4cc043fa064bb7f1dab95a71d1918ec1eef7b55 android.hardware.media.omx@1.0::IGraphicBufferSource
+0d3de9cd89d4718ea3b772f2d8b93be004feb3abb7e7dc5402e37047cc730d05 android.hardware.media.omx@1.0::IOmx
+32002e1c358c64de106c977a6dc6af7da27be4803a5bb66fd6f891a5ba0a1617 android.hardware.media.omx@1.0::IOmxBufferSource
+81ad8d8bb1cf6f41923cf11dd39354a8fe433db284a234cc675de7e75a82224c android.hardware.media.omx@1.0::IOmxNode
+494c0c8bf6065edc82ec127228ed19dd2243dc1c2f7d601c7c6be7b7015c1713 android.hardware.media.omx@1.0::IOmxObserver
+252c2fc50c78fd6de8365e5b60e5115119ace107db0b94b0b26815cbf3d2b64a android.hardware.media.omx@1.0::IOmxStore
+148c1b50b0958988373145ffdf5fa0e1b6534e0a2034a570e74b15c127cf7c5e android.hardware.media.omx@1.0::types
+c66902fe48d687ac6740a3e32ae55fb75532c48c36c6386461c2b4416ad2e0f1 android.hardware.memtrack@1.0::IMemtrack
+860bacd8b11a269c40567542b613fe4ca448d5cb4326d0058899e608e89dfca1 android.hardware.memtrack@1.0::types
+07ac2dc95270321ec7d4c33cd25e5085a057f47fe350d645af6f7a7a11e3cf57 android.hardware.nfc@1.0::INfc
+f2fe54426c07d67388d4774a60641ad4c0538f22eb6e1111722f231772655de6 android.hardware.nfc@1.0::INfcClientCallback
+9626fd18db113d709faf593a70caf19bd0980294d23c468c80c30186f9d298a6 android.hardware.nfc@1.0::types
+deee1dc4948f33af207e1008aba0f6cc07afb7900eab53f33192c8cac137eefc android.hardware.power@1.0::IPower
+efc83df3f962b93c7c0290d691d7d300dabe12683e2cde3591fb3c0beedce20f android.hardware.power@1.0::types
+9b5aa499ec3b4226f15f48f5ed08896e2fc0676f978c9e199c1da21daaf002a6 android.hardware.radio@1.0::IRadio
+5c8efbb9c451a59737ed2c6c20230aae4745839ca01d8088d6dcc9020e52d2c5 android.hardware.radio@1.0::IRadioIndication
+69f6b4b8ec40ca02ccc7bb8227a097135c20c00bd94c822e421cd9af1267252c android.hardware.radio@1.0::IRadioResponse
+de3ab9f73b1073cd677b19d886fb927e9381b30161a704712d2b30f875873f5c android.hardware.radio@1.0::ISap
+d183e406ef0897df2117a9dde384e8e6ea4fa6ab1c7f6f28e65b87011218c9ea android.hardware.radio@1.0::ISapCallback
+96986fbd22f0e6ca752e1fcdc0a64bda213995a81f5f36bc4faf3532d9306b97 android.hardware.radio@1.0::types
+00f70085d6fae1d482fb700a3fd42ed475384c95b51c9269b9ae5037b74ad4dd android.hardware.radio.deprecated@1.0::IOemHook
+06837b6d7e843cfa9cd20fed4070feca7a9b5c81a9ed643bf7d06803455a9816 android.hardware.radio.deprecated@1.0::IOemHookIndication
+6fd4874f0eddd4626a27658fd94fad526c317f3563439e79718bdb1a3a2309d5 android.hardware.radio.deprecated@1.0::IOemHookResponse
+6983a2cafe39d5c57dfdc1743055fb0f757a0df8c78e00423d5e1810836927e1 android.hardware.renderscript@1.0::IContext
+7f9417a0ccf78ea042ec7a8ac8e3750346d4d9d7e5ae01b1b35fde303f47c24d android.hardware.renderscript@1.0::IDevice
+fc6f325b266b32353f7d1534fbe58e0d368265a12b77fa396fb556e8c443f739 android.hardware.renderscript@1.0::types
+89585ff541c319de4091a5a0b687dd526ac81c6382ffd7b979a4164b3d7419a6 android.hardware.sensors@1.0::ISensors
+e04ab978fc28f4c515f4a75617dfda8607733a64f13666beeb0e604a07a39333 android.hardware.sensors@1.0::types
+5befc019cbe94953661e2cdb95e3cf64f5e565c29403e1c2daecc2be44e0a55c android.hardware.soundtrigger@2.0::ISoundTriggerHw
+d7ec5f612a5e0a59ea4f2b61317e208ff56dd50920fd4eb441e0cbc8f97e4f49 android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
+5bee9e70f7e5ec7ee252883b28f98f12b59960f4c2a0b4cc9a4526e4669ebcd4 android.hardware.soundtrigger@2.0::types
+97f1ec446043bc5a6645b74529a6276496bdb35e0aee41eda55cb92d51eb7802 android.hardware.thermal@1.0::IThermal
+84965a6908bceb4ef51546bf8731f309f1ea9d09a0177dcc7974132e523dd6d2 android.hardware.thermal@1.0::types
+938850621c3c5ef426a4b88e752ba99b3559037e782a3d938604f3aef5cc0f1b android.hardware.tv.cec@1.0::IHdmiCec
+e75b6eea711d36fac678bce072b3cec6544b27fa9f4cd903999404e5c110ca10 android.hardware.tv.cec@1.0::IHdmiCecCallback
+6e25f8dbfadb668e1d4ec80eb9acd95d8bc9e0a240c36d27e662adb440314b95 android.hardware.tv.cec@1.0::types
+0cafa3c8388e9631916d2d800f78decbcec2904f11415b32c71a31d9a51ebf79 android.hardware.tv.input@1.0::ITvInput
+dee83e5c864fbbee8f02448d0800be32f06856386b9f907bc5d952208c9434f9 android.hardware.tv.input@1.0::ITvInputCallback
+07aab30410b612381234dca6d453d4ab96f2e536368715717c6e28101b9851b5 android.hardware.tv.input@1.0::types
+4ef57499273f38bdbdd0c15e56ee7a4bc5f18a5644092170a531df3541d9e015 android.hardware.usb@1.0::IUsb
+4be7881e411ba42784bf5b7354c14ae0cf161004d39433aaecaab0d19ea99354 android.hardware.usb@1.0::IUsbCallback
+f7e6e747910a3cd0a35846141e3b990a6a612a297b2b70ccd5740b646a450a8c android.hardware.usb@1.0::types
+06ea64cc3565777f3b259e400ffa7100d07f3827ad9357b0c5d3c651384e5553 android.hardware.vibrator@1.0::IVibrator
+0fecd34ae64f32eff6aa615fd662349242c0b8b6e303ef05a7cb5776c732f413 android.hardware.vibrator@1.0::types
+4b962968a7df4ab104d1315d66a0a7348a713fecbb5d2c1b23688494458f37ce android.hardware.vr@1.0::IVr
+b9be36719a8ad534000a51ea07be91be94c405bf1e038ae825acf65087ffd378 android.hardware.wifi@1.0::IWifi
+ee0224ee18813506d9d6f13d8c8e4679f053c290a443a52a7c52a5d3c852262b android.hardware.wifi@1.0::IWifiApIface
+f3eecc489deb4c74892f59eb7adb769063bd5c354ac132b626a5f42b363d36bc android.hardware.wifi@1.0::IWifiChip
+a1b988377645a58e5e2542ca2bad4e17c21a4a389213d05de2f0e32d57b7d339 android.hardware.wifi@1.0::IWifiChipEventCallback
+5ed6760ce77e84bc6c49d1acb3f7d8117c9176b3f06514bc44ad3af84c80dcfe android.hardware.wifi@1.0::IWifiEventCallback
+6b9ad43a5efbe6ca214f751e22ce43cf5cd4d5d5f2cba80f24ccd3755a72401c android.hardware.wifi@1.0::IWifiIface
+ba5aa74f1ba714f0093864227923492808795bda6199c4ea0891322d27f8c931 android.hardware.wifi@1.0::IWifiNanIface
+325c94f3e1a565b56bbc74faddbd0ba7cb824f263dccf9dfff2daf62b86ed774 android.hardware.wifi@1.0::IWifiNanIfaceEventCallback
+c2c3f0372b41780fb6dfe83c022296806c2024d7046682fd201de5aa9b791c7a android.hardware.wifi@1.0::IWifiP2pIface
+766e9765f5c9c759b2a763c2288353fb5deff3389c2cc28f81d79c939704ce8b android.hardware.wifi@1.0::IWifiRttController
+72ab6f3e120cbf07aa6f8e87ca89112bdeb36b7fbb96bce5af3712323ab8b8e6 android.hardware.wifi@1.0::IWifiRttControllerEventCallback
+3b8093d39ef1e10e43c5538afbf5ff6e39b8d8168ebbe1998d993e89e25f14a5 android.hardware.wifi@1.0::IWifiStaIface
+7fbfc551c3e23c8b4398c3e16e452b516457e6921424a53474cbf373ca306fa9 android.hardware.wifi@1.0::IWifiStaIfaceEventCallback
+e20d5132d6d23e072c15de065b5e2aa13ff965031246a2c82581732bae56bf6d android.hardware.wifi@1.0::types
+f7e55c08187d8c855068a1ee3d0c8daeee7570292d96509c21a8756d4f5cfb9b android.hardware.wifi.supplicant@1.0::ISupplicant
+56b5c7267cb3d3337f44eb8b0b38ff4c6260dcc70e07687fcab94b1ccea8d159 android.hardware.wifi.supplicant@1.0::ISupplicantCallback
+35ba7bcdf18f24a866a7e5429548f06768bb20a257f75b10a397c4d825ef8438 android.hardware.wifi.supplicant@1.0::ISupplicantIface
+cda01008c06922fa37c1213e9bb831a109b3174532805616fb7161edc403866f android.hardware.wifi.supplicant@1.0::ISupplicantNetwork
+4907410338c5e8dbeec4b5edc2608ea323f5561945f8810af81810c47b019184 android.hardware.wifi.supplicant@1.0::ISupplicantP2pIface
+8b63f5efa2e3be3a7cb8a428760d82285a4ab79bcbdea6ef90aa547555e582d4 android.hardware.wifi.supplicant@1.0::ISupplicantP2pIfaceCallback
+56128f74560571b6777d59453f35c6b35693ee377e2a23c807708906928f09de android.hardware.wifi.supplicant@1.0::ISupplicantP2pNetwork
+2067c22197bca9743dab66a6f561a8a8375c67b4f76aed05f776839499bd4c8f android.hardware.wifi.supplicant@1.0::ISupplicantP2pNetworkCallback
+7752e1de93aaf5fed37011c219ac247069f6af320b0810daa98510584a10e7b4 android.hardware.wifi.supplicant@1.0::ISupplicantStaIface
+d781c8d7e7b3fe5cca8cf6e1d8806e770982ae5358c7816ed51b0f0ec272e70d android.hardware.wifi.supplicant@1.0::ISupplicantStaIfaceCallback
+b12ef0bdd8a4d247a8a6e960b227ed32383f2b0241f55d67fcea6eff6a6737fa android.hardware.wifi.supplicant@1.0::ISupplicantStaNetwork
+d8f0877ae1d321c1d884c7631dfe36cab0ec8a4b2863d4b687f85d3549a63bcc android.hardware.wifi.supplicant@1.0::ISupplicantStaNetworkCallback
+fe3c3c2f572b72f15f8594c538b0577bd5c28722c31879cfe6231330cddb6747 android.hardware.wifi.supplicant@1.0::types
+
+# ABI preserving changes to HALs during Android O MR1 (Initial Set)
+
+150a338ce11fcec70757c9675d83cf6a5d7b40d0c812741b91671fecce59eac9 android.hardware.broadcastradio@1.0::types
+dc7e6d4f537b9943e27edc4f86c5a03bb643b18f18f866f8c3c71c0ac4ea8cbc android.hardware.broadcastradio@1.0::types
+760485232f6cce07f8bb05e3475509956996b702f77415ee5bff05e2ec5a5bcc android.hardware.dumpstate@1.0::IDumpstateDevice
+78589343d8ee2e1b155acad3fbdc7fcbb6af94491aee968b2383c21627264f8b android.hardware.radio@1.0::IRadioResponse # Available in Android O, b/68061860
+e822cb7f4a1bdd45689c5e92ccd19a2201c20b771bd4b2ec1ae627e324591f9d android.hardware.radio@1.0::IRadioResponse
+6e69adb24d7c0b0ca3a54a38c49a5625b161b3f5d5f7d6fda0befdbbfc8e9e06 android.hardware.radio@1.0::IRadioResponse
+c2c50ec74c87a583c683b4493f8f9f2e454a8d41c57af5b3eb88823a999f0ea4 android.hardware.radio@1.0::IRadioResponse # Added for b/65230472 for Android O
+4922dd58e89a03181ed1c48a6e118e47633b73b11090bdfed5aa920d25a7592b android.hardware.radio@1.0::IRadioResponse # Added for b/65230472 for Android O DR
+28e929b453df3d9f5060af2764e6cdb123ddb893e3e86923c877f6ff7e5f02c9 android.hardware.wifi@1.0::types
+df1d7b27e644bfed0a4f606a8c44d35d45cafce82c7c648494c8a25c7cd4a949 android.hardware.wifi@1.0::types
+
+# HALs released in Android O MR1 (Initial Set)
+
+4b65763663a94a3920134011691f8fbb42ccb7b7795589efddc049a9106047d6 android.hardware.oemlock@1.0::IOemLock
+e02cd3722cb5e8fa51179f5defacb4f7866f903c9c7c51dc01a3148473a71525 android.hardware.oemlock@1.0::types
+224f9d22a367a0016f09b6dc676f53f1446697d9dc747163032329e5da552de5 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
+b056e1defab4071584214584057d0bc73a613081bf1152590549649d4582c13c android.hardware.wifi@1.1::IWifiChip
+
+# ABI preserving changes to HALs during Android O MR1 (Final Set)
+09342041e17c429fce0034b9096d17849122111436a5f0053e7e59500e1cb89c android.hardware.media.omx@1.0::IOmxStore
+2d833aeed0cd1d59437aca210be590a953cf32bcb6683cd63d089762a643fb49 android.hardware.radio@1.0::IRadioResponse
+0a159f81359cd4f71bbe00972ee8403ea79351fb7c0cd48be72ebb3e424dbaef android.hardware.radio@1.0::types
+05aa3de6130a9788fdb6f4d3cc57c3ea90f067e77a5e09d6a772ec7f6bca33d2 android.hardware.radio@1.1::IRadioResponse
+
+# HALs released in Android O MR1 (Final Set)
+044cb039378b8a0e36f40ff1e6ce04dc0d339da02095f968d5062a051e99d108 android.hardware.broadcastradio@1.1::types
+c9699483f8cefe4f9b39b4b9609b76cab2dd1659a06188056b45797d337d4256 android.hardware.broadcastradio@1.1::IBroadcastRadio
+b5d62dcd663fc4fcc977b252af59b333043bdfe73de2f11fe6d6a8bf438a0f92 android.hardware.broadcastradio@1.1::IBroadcastRadioFactory
+bc7e054a6e93adebedff345aeed44549be89e6b1b6ffe071ff47a61de764b232 android.hardware.broadcastradio@1.1::ITuner
+e9139fc755be578693f17c8cd1e27c75f412cfc722157bab5bf03ee68896e31d android.hardware.broadcastradio@1.1::ITunerCallback
+63929c99e5755d9e09d9e0fd2527391fbb1609dda0508f5933b7943b92ae0fbc android.hardware.camera.device@3.3::types
+bbcfc3f748b078f6a66c4e228084a679d30bd61bfde8bb7a91efd507b91c1bfd android.hardware.camera.device@3.3::ICameraDeviceSession
+4a6998cd6793a3f9f03989c29d662589b1bc9d38826c6698c6c17864f7a814f5 android.hardware.cas@1.0::types
+0e656ba1bac11461a17096ef752b69d24b000d820ef5652f0150a0f9731d54c2 android.hardware.cas@1.0::ICas
+b80e1456b81f80032d0de7cb45652ac15af11e7474d520d757481ecaad796dff android.hardware.cas@1.0::ICasListener
+a432d6d9200248dc2126827bcd6cdea31dd65eff39b939f64585d27d915a5857 android.hardware.cas@1.0::IDescramblerBase
+86ba9c03978b79a742e990420bc5ced0673d25a939f82572996bef92621e2014 android.hardware.cas@1.0::IMediaCasService
+503da837d1a67cbdb7c08a033e927e5430ae1b159d98bf72c6336b4dcc5e76f5 android.hardware.cas.native@1.0::types
+619600109232ed64b827c8a11beed8070b1827ae464547d7aa146cf0473b4bca android.hardware.cas.native@1.0::IDescrambler
+93eb3757ceaf21590fa4cd1d4a7dfe3b3794af5396100a6d25630879352abce9 android.hardware.neuralnetworks@1.0::IDevice
+f66f9a38541bf92001d3adcce678cd7e3da2262124befb460b1c9aea9492813b android.hardware.neuralnetworks@1.0::IExecutionCallback
+953607822954435874f4b81686440a604e2a88cdd2d9164c6293f3d5772510d7 android.hardware.neuralnetworks@1.0::IPreparedModel
+73e03573494ba96f0e711ab7f1956c5b2d54c3da690cd7ecf4d6d0f287447730 android.hardware.neuralnetworks@1.0::IPreparedModelCallback
+246a56d37d57a47224562c9d077b4a2886ce6242b9311bd98a17325944c280d7 android.hardware.neuralnetworks@1.0::types
+f4945e397b5dea41bb64518dfde59be71245d8a125fd1e0acffeb57ac7b08fed android.hardware.thermal@1.1::IThermal
+c8bc853546dd55584611def2a9fa1d99f657e3366c976d2f60fe6b8aa6d2cb87 android.hardware.thermal@1.1::IThermalCallback
+
+# ABI preserving changes to HALs during Android P
+9e7a0b650d0e461ece2cfec0e1072abf8676f592b41a7fb48f01e88fc3c8f780 android.hardware.broadcastradio@1.0::types
+cf72ff5a52bfa4d08e9e1000cf3ab5952a2d280c7f13cdad5ab7905c08050766 android.hardware.camera.metadata@3.2::types
+3902efc42097cba55f0655aa389e052ea70164e99ced1a6d1ef53dafc13f7650 android.hardware.camera.provider@2.4::ICameraProvider
+6fa9804a17a8bb7923a56bd10493a5483c20007e4c9026fd04287bee7c945a8c android.hardware.gnss@1.0::IGnssCallback
+fb92e2b40f8e9d494e8fd3b4ac18499a3216342e7cff160714c3bbf3660b6e79 android.hardware.gnss@1.0::IGnssConfiguration
+251594ea9b27447bfa005ebd806e58fb0ae4aad84a69938129c9800ec0c64eda android.hardware.gnss@1.0::IGnssMeasurementCallback
+4e7169919d24fbe5573e5bcd683d0bd7abf553a4e6c34c41f9dfc1e12050db07 android.hardware.gnss@1.0::IGnssNavigationMessageCallback
+190ea4898809de6cf379afe318f5fa9564686157b24d9a2d7f5698b0c977d8b2 android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer
+25892789b50eb673506b6c5a2cdab5d9aa428d41608aab10280cc898538b524a android.hardware.graphics.composer@2.1::IComposerClient
+e205dd30f5ff99445b706a901de8ebc46c379e9d7c1921d6a327ed2082cfa83d android.hardware.graphics.composer@2.1::types
+a46251718abfada458dc64c41ce94915757bf6c87cfa2d9e99cfb01fa8e32331 android.hardware.graphics.mapper@2.0::IMapper
+bd33ac23c57b4a07632691d2191bc2c93930f57e62f4ccf459748fdaa5c0f480 android.hardware.graphics.mapper@2.0::types
+ad8a28ca3a5549fb9bc24cf5f80ac8f660cc27be885210d76266780aa52ddb8d android.hardware.keymaster@3.0::types
+5804ca86611d72e5481f022b3a0c1b334217f2e4988dad25730c42af2d1f4d1c android.hardware.neuralnetworks@1.0::IDevice
+12e8dca4ab7d8aadd0ef8f1b438021938e2396139e85db2ed65783b08800aa52 android.hardware.neuralnetworks@1.0::IExecutionCallback
+86b77e06da756a76aa3685be88765852dd982a86d8c90b8b4fc1130ed4184c8f android.hardware.neuralnetworks@1.0::types
+d4840db8efabdf1e4b344fc981cd36e5fe81a39aff6e199f6d06c1c8da413efd android.hardware.radio@1.0::types
+f96cbc59dfe16c8d0c2a7e06db24d8738a6328b6e90f7b8e1640ea2b4600debd android.hardware.radio@1.1::ISap
+2d86929794795e5c70f4fdb5073485fd05835c9c6f496116687c3d9f32e6df3e android.hardware.radio@1.2::ISap
+905a4af79c8329b39d8b11b08f015137216bb078b427b6986f32884a04bc1bec android.hardware.tv.cec@1.0::types
+aebcd9ff2da05c9d4c439916f40dfd219ba7629919007cb981ebf150064b4f82 android.hardware.usb@1.1::IUsb
+e29fb1941b40a990676f8e9c676a38761defd890b81a9c034608eb7ba6496023 android.hardware.wifi@1.0::IWifiP2pIface
+b280c4704dfcc548a9bf127b59b7c3578f460c50cce70a06b66fe0df8b27cff0 android.hardware.wifi@1.0::types
+
+# HALs released in Android P
+5860cf040a3d5d771967ecf648b00d06876a7120da985ee2b3e95d01f634dd20 android.hardware.audio@4.0::IDevice
+cf82a0249e918fdc657e189895e92d60af0491868477e82cdc30f6cab0ca2c65 android.hardware.audio@4.0::IDevicesFactory
+be3dc9baed45a0d330152eca3ca24fa419b375b20a41644c88d4fb46b72784d2 android.hardware.audio@4.0::IPrimaryDevice
+3e3acb70c4e6c7d578f511f4a44ee764ab9126f887a3bf65d523c42e40012bf6 android.hardware.audio@4.0::IStream
+d5de64e66b95f135dd42492250a309134b8227203ef3524440798c66b6f5a392 android.hardware.audio@4.0::IStreamIn
+888ac906461327fa0bd93854d5109be8c292a33afdb467164826970a8bd5b789 android.hardware.audio@4.0::IStreamOut
+15f6ae78e73344c8e7d68847ef03caec64fcd9f951bbcf59957d1712c247fcff android.hardware.audio@4.0::IStreamOutCallback
+61f0eaa4d08547d039e9b1dd7c82abe2c004286d1b9b8153c2491ff46a8a63ca android.hardware.audio@4.0::types
+5d47a2ad2c136b8aba067dd45bb10d0ad390dd76340764154f580658f98f4fe6 android.hardware.audio.common@4.0::types
+b04b6b364938b80008e61fa2e318bc299622433e57c2e1f6cfba332a3f6e3f15 android.hardware.audio.effect@4.0::IAcousticEchoCancelerEffect
+1c17d4ece5c8ba3f7a646a305ee0dd109b0d51372e1bd585812e513cd40e1852 android.hardware.audio.effect@4.0::IAutomaticGainControlEffect
+34174259fe6fbb1bb14e7103e097f2f25529271a676687845b2f55d6d0d9d617 android.hardware.audio.effect@4.0::IBassBoostEffect
+7a18e9bd0163f3784448f6e24be0db75f877e2f0f9bd0d7ec427f1c34b382c0b android.hardware.audio.effect@4.0::IDownmixEffect
+bac81bffbe2661d5b6839087d2dd3a27eded66e60c6c76d35c68d54014cd5c06 android.hardware.audio.effect@4.0::IEffect
+65f0bcf9e498b26f3266ad10cf513a6c2b5906cc49f9db4bc5c7d3ba11a72e05 android.hardware.audio.effect@4.0::IEffectBufferProviderCallback
+5a746e81175489eb2371b88864c36c9bb63bc64ef799fae74cd96003b013c0d1 android.hardware.audio.effect@4.0::IEffectsFactory
+839980c7c5be79da6b95fdb9354a62b04407b4b084749b7a21d2c340773d7638 android.hardware.audio.effect@4.0::IEnvironmentalReverbEffect
+2805fbdac7cff050a1c095b9276bb41ac02a3b7b354336817487eb9a4b6bb462 android.hardware.audio.effect@4.0::IEqualizerEffect
+a91b547f5922f39fe4231d97fac1c3825c1c1b0c8ef7a5136689ceed37e8bfe9 android.hardware.audio.effect@4.0::ILoudnessEnhancerEffect
+1145f5b921ddec184fda5bdc87487b46f2a89cd9f42cc882bbb3a54f4ac80466 android.hardware.audio.effect@4.0::INoiseSuppressionEffect
+3661fa0623056922fdc4235ac5a9c91a2d066ab6f1ab4297e3b240fe302ba500 android.hardware.audio.effect@4.0::IPresetReverbEffect
+e88e520f8c98a62fccd8d5316c6687808f775de145d1405a7a9a66587ee6a001 android.hardware.audio.effect@4.0::IVirtualizerEffect
+fe28829dab10d171783b79ac9cc45412739f8ff275e90228d7c6370ef189b859 android.hardware.audio.effect@4.0::IVisualizerEffect
+21c8a702579356480236c6851b5b2c16b9bd369ce12bdd6ffdc4626a89f34f73  android.hardware.audio.effect@4.0::types
+42a06dc288f61b0690580f3d37b30b663c31d74d50bb58d0772386b550d5faab android.hardware.authsecret@1.0::IAuthSecret
+32cc50cc2a7658ec613c0c2dd2accbf6a05113b749852879e818b8b7b438db19 android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioHost
+ff4be64d7992f8bec97dff37f35450e79b3430c61f85f54322ce45bef229dc3b android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioOffload
+27f22d2e873e6201f9620cf4d8e2facb25bd0dd30a2b911e441b4600d560fa62 android.hardware.bluetooth.a2dp@1.0::types
+3d8ed67d807e9f15d0708390a416bee00920f6a22196c104cc9e443c8d217df8 android.hardware.broadcastradio@2.0::IAnnouncementListener
+44017c42e6f4d8cb30f07eb1da04540a98736a336ac28c7e0ed2e69e1589f8d1 android.hardware.broadcastradio@2.0::IBroadcastRadio
+e5f4960290b4f3089163dd43251e1a032c81e9bdb796e75a87fc7c5810c262b3 android.hardware.broadcastradio@2.0::ICloseHandle
+af24b87ca8b8f02fcde205e47db6a9609fc7e9d77d73e694ec8f9c508ca19575 android.hardware.broadcastradio@2.0::ITunerCallback
+d70464c517a4a1b5167730843775a97f455102919e945b04f717b9da390c0f39 android.hardware.broadcastradio@2.0::ITunerSession
+2afa59ebf8145e7fbc090cf49605c27280c07d4178d47cd7f9d82b3b95a47af0 android.hardware.broadcastradio@2.0::types
+4fb0725c36ed4f77a42b42e3f18d8b5f7919cb62b90098b23143a555aa7dd96d android.hardware.camera.device@3.4::ICameraDeviceCallback
+812fa66aa10ba0cba27cfddc2fd7f0ee27a8ab65a1f15aa79fdad97d403e6a14 android.hardware.camera.device@3.4::ICameraDeviceSession
+cc288f1f78d1e643eb3d3dbc16e1401d44033d8e6856761f5156814a29986ec7 android.hardware.camera.device@3.4::types
+f9278c8beb9d42d96e26d73ecabe1dff1d7e2fb301ab7f737d93e5ffae8d3312 android.hardware.camera.metadata@3.3::types
+f858091b10f7d5927be60573c06df4805275d37226bbb41a732190bfb81457ec android.hardware.configstore@1.1::ISurfaceFlingerConfigs
+5b0fb9842f8b0eb3730b93c30a7925290ab44763ab86bb493bfa58d0f2eeb369 android.hardware.configstore@1.1::types
+1a46aeae45b7a0e47f79b7207300532986f9d9cd7060779afc7a529f54d712ab android.hardware.confirmationui@1.0::IConfirmationResultCallback
+6d8347ff3cd7de471065ac3e8e68385073630cdeebe9f8fa58cb91cf44436c95 android.hardware.confirmationui@1.0::IConfirmationUI
+a3ff916784dce87a56c757ab5c86433f0cdf562280999a5f978a6e8a0f3f19e7 android.hardware.confirmationui@1.0::types
+1fbf2d7e383632216aaaa1d972a21a618f55659263d2e6f0b309e3cb323b4b63 android.hardware.drm@1.1::ICryptoFactory
+7877ff8e4c1e48b825e6e5e66d050288e5656ed535c61cc7830a92ed4a9e1990 android.hardware.drm@1.1::IDrmFactory
+fef2f0ebde7704548fb203df46673ceb342272fc4fa9d0af25a980d2584a36e7 android.hardware.drm@1.1::IDrmPlugin
+5047a346ecce239404b9020959f60dd467318e9c17b290a6386bc3894df62c3c android.hardware.drm@1.1::types
+a830336ac8627d6432cfafb1b884343ad9f885dee0a5323e380e6d3c519156b8 android.hardware.gnss@1.1::IGnss
+8ad55bc35bb3a83e65c018bdfde7ae5ebc749ff2bf6b79412ded0bc6c89b97d8 android.hardware.gnss@1.1::IGnssCallback
+3c5183d7506010be57e0f748e3640fc2ded1ba955784b6256ba427f4c399591c android.hardware.gnss@1.1::IGnssConfiguration
+1a07d1383e847c3deb696ec7a2c9e33b9683772945660448a010b18063da67a4 android.hardware.gnss@1.1::IGnssMeasurement
+83e7a10ff3702147bd7ffa04567b20d407a3b16bbb7705644af44d919afe9103 android.hardware.gnss@1.1::IGnssMeasurementCallback
+0b96e0254e2168cfecb30c1ed5fb42681652cc00faa68c6e07568fafe64d1d50 android.hardware.graphics.common@1.1::types
+7d2cef99c838fb58038de8bbfd3cdb76ff4797241987077721715297f8d45e34 android.hardware.graphics.common@1.1::types # b/78135149
+d9b40a5b09962a5a0780b10fe33a4e607e69e2e088fc83de88a584115b7cb1c0 android.hardware.graphics.composer@2.2::IComposer
+a2f183f7fcc79aabedaef11095ab223aac0ed5ef984d850893872515e7f560c7 android.hardware.graphics.composer@2.2::IComposerClient
+dd83be076b6b3f10ed62ab34d8c8b95f2415961fb785200eb842e7bfb2b0ee92 android.hardware.graphics.mapper@2.1::IMapper
+675682dd3007805c985eaaec91612abc88f4c25b3431fb84070b7584a1a741fb android.hardware.health@2.0::IHealth
+434c4c32c00b0e54bb05e40c79503208b40f786a318029a2a4f66e34f10f2a76 android.hardware.health@2.0::IHealthInfoCallback
+c9e498f1ade5e26f00d290b4763a9671ec6720f915e7d592844b62e8cb1f9b5c android.hardware.health@2.0::types
+201f9723353fdbd40bf3705537fb7e015e4c399879425e68688fe0f43606ea4d android.hardware.keymaster@4.0::IKeymasterDevice
+1b7d2090c0a28b229d37c4b96160796b1f0d703950ac6ccc163fccd280830503 android.hardware.keymaster@4.0::types
+6d5c646a83538f0f9d8438c259932509f4353410c6c76e56db0d6ca98b69c3bb android.hardware.media.bufferpool@1.0::IAccessor
+b8c7ed58aa8740361e63d0ce9e7c94227572a629f356958840b34809d2393a7c android.hardware.media.bufferpool@1.0::IClientManager
+4a2c0dc82780e6c90731725a103feab8ab6ecf85a64e049b9cbd2b2c61620fe1 android.hardware.media.bufferpool@1.0::IConnection
+6aef1218e5949f867b0104752ac536c1b707222a403341720de90141df129e3e android.hardware.media.bufferpool@1.0::types
+7698dc2382a2eeb43541840e3ee624f34108efdfb976b2bfa7c13ef15fb8c4c4 android.hardware.neuralnetworks@1.1::IDevice
+72cc6126632456e8fbb8776fe50150c3c4dd5d09145653193affb70785211dfa android.hardware.neuralnetworks@1.1::types
+8d3d86da0bfa4bf070970d8303c659f67f35d670c287d45a3f542e4fedadd578 android.hardware.nfc@1.1::INfc
+e85f566698d2a2c28100e264fcf2c691a066756ddf8dd341d009ff50cfe10614 android.hardware.nfc@1.1::INfcClientCallback
+5e278fcaa3287d397d8eebe1c22aaa28150f5caae1cf9381cd6dc32cb37899c5 android.hardware.nfc@1.1::types
+163e115e833fc1d77cdd4a8cf0c833bb8b8d74fe35c880fe693101d17774926f android.hardware.power@1.2::IPower
+7899b9305587b2d5cd74a3cc87e9090f58bf4ae74256ce3ee36e7ec011822840 android.hardware.power@1.2::types
+ab132c990a62f0aca35871c092c22fb9c85d478e22124ef6a4d0a2302da76a9f android.hardware.radio@1.2::IRadio
+cda752aeabaabc20486a82ac57a3dd107785c006094a349bc5e224e8aa22a17c android.hardware.radio@1.2::IRadioIndication
+da8c6ae991c6a4b284cc6e445332e064e28ee8a09482ed5afff9d159ec6694b7 android.hardware.radio@1.2::IRadioResponse
+b65332996eb39ba63300a1011404141fa59ce5c252bc17afae637be6eeca5f55 android.hardware.radio@1.2::ISap
+a9361522cc97ef66209d39ba324095b2f08344054bb4d3481e803eee0480623a android.hardware.radio@1.2::types
+87385469cf4409f0f33b01508e7a477cf71f2a11e466dd7e3ab5971a1baaa72b android.hardware.radio.config@1.0::IRadioConfig
+228b2ee3c8c276c9f0afad2dc313ca3d6bbd9e482ddf313c7204c60ad9b636ab android.hardware.radio.config@1.0::IRadioConfigIndication
+a2e9b7aa09f79426f765838174e04b6f9a3e6c8b76b923fc1705632207bad44b android.hardware.radio.config@1.0::IRadioConfigResponse
+4307696b64ded9bd8de06887f9dfc533e875c4e0d83b8008df4d705164bde0b1 android.hardware.radio.config@1.0::types
+bd7699f07ba5392310fefd33ea964e01f4f4a66015146845c85055004823cc81 android.hardware.secure_element@1.0::ISecureElement
+a65aa82bbe48d81a9ae9e86247bb1b89fd2d3138d4053d7a5b716c71149b7dee android.hardware.secure_element@1.0::ISecureElementHalCallback
+2984c069f48ba35cd1bf49b0e17daad0d418fef52cb7a4a84dba0043114063d4 android.hardware.secure_element@1.0::types
+b4f507b4dc9b5cd5f0e4445926acb7d94525ae60dc307b3951142283632207b6 android.hardware.soundtrigger@2.1::ISoundTriggerHw
+92c2cc0f06ef744c5bda21f1d660258f7937203109b493eee22c3f3e2dbb0d3e android.hardware.soundtrigger@2.1::ISoundTriggerHwCallback
+8ddfa7542772cc7bca19972b2d856264efa31914bfd098aeb7c2079d950194cb android.hardware.usb.gadget@1.0::IUsbGadget
+ad0a620cda08f01b151c30cb7afa23b0637cc84340cf8dec00ac8e32cf54a8db android.hardware.usb.gadget@1.0::IUsbGadgetCallback
+51fc20f223561ac3a32ace3217837ef3860265bd91c8b7ae3859532caef9bc39 android.hardware.usb.gadget@1.0::types
+1bfc9fd9536ed09f04bcaf222a332bc919f1565d4d08bddccdebe1bfca8f01b5 android.hardware.vibrator@1.2::IVibrator
+a0aefa29881235c21e4761d15c55edc35ef85c2e0d9e01d0966176d1dbf5f811 android.hardware.vibrator@1.2::types
+8bc75a0dfac15c6f87ffec950b76c7d7de30d516b54e8e0b1f3c0ff9c7c6873b android.hardware.wifi@1.2::IWifi
+780c16fdeda13b779d993953a67f7ca578c938a172a9424c1c715ae81bc40fd7 android.hardware.wifi@1.2::IWifiChip
+167af870fdb87e1cbbaa0fa62ef35e1031caad20dd1ba695983dedb1e9993486 android.hardware.wifi@1.2::IWifiChipEventCallback
+8c7ef32fc78d5ec6e6956de3784cc2c6f42614b5272d2e461f6d60534ba38ec2 android.hardware.wifi@1.2::IWifiNanIface
+1e6074efad9da333803fb7c1acdb719d51c30b2e1e92087b0420341631c30b60 android.hardware.wifi@1.2::IWifiNanIfaceEventCallback
+f5682dbf19f712bef9cc3faa5fe3dc670b6ffbcb62a147a1d86b9d43574cd83f android.hardware.wifi@1.2::IWifiStaIface
+6db2e7d274be2dca9bf3087afd1f774a68c99d2b4dc7eeaf41690e5cebcbef7a android.hardware.wifi@1.2::types
+ee08280de21cb41e3ec26d6ed636c701b7f70516e71fb22f4fe60a13e603f406 android.hardware.wifi.hostapd@1.0::IHostapd
+b2479cd7a417a1cf4f3a22db4e4579e21bac38fdcaf381e2bf10176d05397e01 android.hardware.wifi.hostapd@1.0::types
+e362203b941f18bd4cba29a62adfa02453ed00d6be5b72cdb6c4d7e0bf394a40 android.hardware.wifi.supplicant@1.1::ISupplicant
+21757d0e5dd4b7e4bd981a4a20531bca3c32271ad9777b17b74eb5a1ea508384 android.hardware.wifi.supplicant@1.1::ISupplicantStaIface
+cd4330c3196bda1d642a32abfe23a7d64ebfbda721940643af6867af3b3f0aa9 android.hardware.wifi.supplicant@1.1::ISupplicantStaIfaceCallback
+10ff2fae516346b86121368ce5790d5accdfcb73983246b813f3d488b66db45a android.hardware.wifi.supplicant@1.1::ISupplicantStaNetwork
diff --git a/prebuilt_hashes/Android.bp b/prebuilt_hashes/Android.bp
new file mode 100644
index 0000000..4692b76
--- /dev/null
+++ b/prebuilt_hashes/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2018 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.
+
+python_binary_host {
+    name: "dump_hals_for_release",
+
+    srcs: [
+        "dump_hals_for_release.py",
+    ],
+
+    version: {
+        py2: {
+            enabled: true,
+        },
+        py3: {
+            enabled: false,
+        },
+    },
+}
diff --git a/prebuilt_hashes/dump_hals_for_release.py b/prebuilt_hashes/dump_hals_for_release.py
new file mode 100755
index 0000000..fee12ab
--- /dev/null
+++ b/prebuilt_hashes/dump_hals_for_release.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 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.
+#
+
+"""
+Dump new HIDL types that are introduced in each dessert release.
+"""
+
+from __future__ import print_function
+
+import argparse
+import collections
+import json
+import os
+import re
+
+class Globals:
+    pass
+
+class Constants:
+    CURRENT = 'current'
+    HAL_PATH_PATTERN = r'/((?:[a-zA-Z_]+/)*)(\d+\.\d+)/([a-zA-Z_]+).hal'
+    CURRENT_TXT_PATTERN = r'(?:.*/)?([0-9]+|current).txt'
+
+def trim_trailing_comments(line):
+    idx = line.find('#')
+    if idx < 0: return line
+    return line[0:idx]
+
+def strip_begin(s, prefix):
+    if s.startswith(prefix):
+        return strip_begin(s[len(prefix):], prefix)
+    return s
+
+def strip_end(s, suffix):
+    if s.endswith(suffix):
+        return strip_end(s[0:-len(suffix)], suffix)
+    return s
+
+def get_interfaces(file_name):
+    with open(file_name) as file:
+        for line in file:
+            line_tokens = trim_trailing_comments(line).strip().split()
+            if not line_tokens:
+                continue
+            assert len(line_tokens) == 2, \
+                "Unrecognized line in file {}:\n{}".format(file_name, line)
+            yield line_tokens[1]
+
+def api_level_to_int(api_level):
+    try:
+        if api_level == Constants.CURRENT: return float('inf')
+        return int(api_level)
+    except ValueError:
+        return None
+
+def get_interfaces_from_package_root(package, root):
+    root = strip_end(root, '/')
+    for dirpath, _, filenames in os.walk(root, topdown=False):
+        dirpath = strip_begin(dirpath, root)
+        for filename in filenames:
+            filepath = os.path.join(dirpath, filename)
+            mo = re.match(Constants.HAL_PATH_PATTERN, filepath)
+            if not mo:
+                continue
+            yield '{}.{}@{}::{}'.format(
+                package, mo.group(1).strip('/').replace('/', '.'), mo.group(2), mo.group(3))
+
+def filter_out(iterable):
+    return iterable if not Globals.filter_out else filter(
+        lambda s: all(re.search(pattern, s) is None for pattern in Globals.filter_out),
+        iterable)
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument('--pretty', help='Print pretty JSON', action='store_true')
+    parser.add_argument('--package-root', metavar='PACKAGE:PATH', nargs='*',
+        help='package root of current directory, e.g. android.hardware:hardware/interfaces')
+    parser.add_argument('--filter-out', metavar='REGEX', nargs='*',
+        help='A regular expression that filters out interfaces.')
+    parser.add_argument('hashes', metavar='FILE', nargs='*',
+        help='Locations of current.txt for each release.')
+    parser.parse_args(namespace=Globals)
+
+    interfaces_for_level = dict()
+
+    for filename in Globals.hashes or tuple():
+        mo = re.match(Constants.CURRENT_TXT_PATTERN, filename)
+        assert mo is not None, \
+            'Input hash file names must have the format {} but is {}'.format(Constants.CURRENT_TXT_PATTERN, filename)
+
+        api_level = mo.group(1)
+        assert api_level_to_int(api_level) is not None
+
+        if api_level not in interfaces_for_level:
+            interfaces_for_level[api_level] = set()
+        interfaces_for_level[api_level].update(filter_out(get_interfaces(filename)))
+
+    for package_root in Globals.package_root or tuple():
+        tup = package_root.split(':')
+        assert len(tup) == 2, \
+            '--package-root must have the format PACKAGE:PATH, but is {}'.format(package_root)
+        if Constants.CURRENT not in interfaces_for_level:
+            interfaces_for_level[Constants.CURRENT] = set()
+        interfaces_for_level[Constants.CURRENT].update(filter_out(get_interfaces_from_package_root(*tup)))
+
+    seen_interfaces = set()
+    new_interfaces_for_level = collections.OrderedDict()
+    for level, interfaces in sorted(interfaces_for_level.items(), key=lambda tup: api_level_to_int(tup[0])):
+        if level != Constants.CURRENT:
+            removed_interfaces = seen_interfaces - interfaces
+            assert not removed_interfaces, \
+                "The following interfaces are removed from API level {}:\n{}".format(
+                    level, removed_interfaces)
+        new_interfaces_for_level[level] = sorted(interfaces - seen_interfaces)
+        seen_interfaces.update(interfaces)
+
+    print(json.dumps(new_interfaces_for_level,
+        separators=None if Globals.pretty else (',',':'),
+        indent=4 if Globals.pretty else None))
+
+if __name__ == '__main__':
+    main()
diff --git a/sensors/1.0/types.hal b/sensors/1.0/types.hal
index 3926e2f..e91820c 100644
--- a/sensors/1.0/types.hal
+++ b/sensors/1.0/types.hal
@@ -1157,8 +1157,7 @@
     Vec3 vec3;
 
     /**
-     * SensorType::ROTATION_VECTOR, SensorType::GAME_ROTATION_VECTOR,
-     * SensorType::GEOMAGNETIC_ROTATION_VECTOR
+     * SensorType::GAME_ROTATION_VECTOR
      */
     Vec4 vec4;
 
@@ -1200,7 +1199,14 @@
     /** SensorType::ADDITIONAL_INFO */
     AdditionalInfo additional;
 
-    /** undefined/custom sensor type >= SensorType::DEVICE_PRIVATE_BASE */
+    /**
+     * The following sensors should use the data field:
+     * - Undefined/custom sensor type >= SensorType::DEVICE_PRIVATE_BASE
+     * - SensorType::ROTATION_VECTOR, SensorType::GEOMAGNETIC_ROTATION_VECTOR:
+     *   - These are Vec4 types with an additional float accuracy field,
+     *     where data[4] is the estimated heading accuracy in radians
+     *     (-1 if unavailable, and invalid if not in the range (0, 2 * pi]).
+     */
     float[16] data;
 };
 
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
index f8b021e..00207b1 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
@@ -94,9 +94,9 @@
 }
 
 void SensorsHidlEnvironmentV1_0::startPollingThread() {
-    stopThread = false;
-    pollThread = std::thread(pollingThread, this, std::ref(stopThread));
-    events.reserve(128);
+    mStopThread = false;
+    mPollThread = std::thread(pollingThread, this, std::ref(mStopThread));
+    mEvents.reserve(128);
 }
 
 void SensorsHidlEnvironmentV1_0::pollingThread(SensorsHidlEnvironmentV1_0* env,
diff --git a/sensors/2.0/default/Android.bp b/sensors/2.0/default/Android.bp
new file mode 100644
index 0000000..11612d3
--- /dev/null
+++ b/sensors/2.0/default/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2018 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_binary {
+    name: "android.hardware.sensors@2.0-service",
+    defaults: ["hidl_defaults"],
+    vendor: true,
+    relative_install_path: "hw",
+    srcs: [
+        "service.cpp",
+        "Sensor.cpp",
+        "Sensors.cpp",
+    ],
+    init_rc: ["android.hardware.sensors@2.0-service.rc"],
+    shared_libs: [
+        "android.hardware.sensors@1.0",
+        "android.hardware.sensors@2.0",
+        "libcutils",
+        "libfmq",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+}
diff --git a/sensors/2.0/default/OWNERS b/sensors/2.0/default/OWNERS
new file mode 100644
index 0000000..2031d84
--- /dev/null
+++ b/sensors/2.0/default/OWNERS
@@ -0,0 +1,2 @@
+bduddie@google.com
+bstack@google.com
diff --git a/sensors/2.0/default/Sensor.cpp b/sensors/2.0/default/Sensor.cpp
new file mode 100644
index 0000000..d3e3f7e
--- /dev/null
+++ b/sensors/2.0/default/Sensor.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2018 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 "Sensor.h"
+
+#include <utils/SystemClock.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::sensors::V1_0::MetaDataEventType;
+using ::android::hardware::sensors::V1_0::SensorFlagBits;
+using ::android::hardware::sensors::V1_0::SensorStatus;
+
+Sensor::Sensor(ISensorsEventCallback* callback)
+    : mIsEnabled(false), mSamplingPeriodNs(0), mLastSampleTimeNs(0), mCallback(callback) {
+    mRunThread = std::thread(startThread, this);
+}
+
+Sensor::~Sensor() {
+    mStopThread = true;
+    mIsEnabled = false;
+    mWaitCV.notify_all();
+    mRunThread.join();
+}
+
+const SensorInfo& Sensor::getSensorInfo() const {
+    return mSensorInfo;
+}
+
+void Sensor::batch(int32_t samplingPeriodNs) {
+    if (samplingPeriodNs < mSensorInfo.minDelay * 1000) {
+        samplingPeriodNs = mSensorInfo.minDelay * 1000;
+    } else if (samplingPeriodNs > mSensorInfo.maxDelay * 1000) {
+        samplingPeriodNs = mSensorInfo.maxDelay * 1000;
+    }
+
+    if (mSamplingPeriodNs != samplingPeriodNs) {
+        mSamplingPeriodNs = samplingPeriodNs;
+        // Wake up the 'run' thread to check if a new event should be generated now
+        mWaitCV.notify_all();
+    }
+}
+
+void Sensor::activate(bool enable) {
+    if (mIsEnabled != enable) {
+        mIsEnabled = enable;
+        mWaitCV.notify_all();
+    }
+}
+
+Result Sensor::flush() {
+    // Only generate a flush complete event if the sensor is enabled and if the sensor is not a
+    // one-shot sensor.
+    if (!mIsEnabled || (mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::ONE_SHOT_MODE))) {
+        return Result::BAD_VALUE;
+    }
+
+    // Note: If a sensor supports batching, write all of the currently batched events for the sensor
+    // to the Event FMQ prior to writing the flush complete event.
+    Event ev;
+    ev.sensorHandle = mSensorInfo.sensorHandle;
+    ev.sensorType = SensorType::ADDITIONAL_INFO;
+    ev.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE;
+    std::vector<Event> evs{ev};
+    mCallback->postEvents(evs);
+
+    return Result::OK;
+}
+
+void Sensor::startThread(Sensor* sensor) {
+    sensor->run();
+}
+
+void Sensor::run() {
+    std::mutex runMutex;
+    std::unique_lock<std::mutex> runLock(runMutex);
+    constexpr int64_t kNanosecondsInSeconds = 1000 * 1000 * 1000;
+
+    while (!mStopThread) {
+        if (!mIsEnabled) {
+            mWaitCV.wait(runLock, [&] { return mIsEnabled || mStopThread; });
+        } else {
+            timespec curTime;
+            clock_gettime(CLOCK_REALTIME, &curTime);
+            int64_t now = (curTime.tv_sec * kNanosecondsInSeconds) + curTime.tv_nsec;
+            int64_t nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
+
+            if (now >= nextSampleTime) {
+                mLastSampleTimeNs = now;
+                nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
+                mCallback->postEvents(readEvents());
+            }
+
+            mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now));
+        }
+    }
+}
+
+std::vector<Event> Sensor::readEvents() {
+    std::vector<Event> events;
+    Event event;
+    event.sensorHandle = mSensorInfo.sensorHandle;
+    event.sensorType = mSensorInfo.type;
+    event.timestamp = ::android::elapsedRealtimeNano();
+    event.u.vec3.x = 1;
+    event.u.vec3.y = 2;
+    event.u.vec3.z = 3;
+    event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
+    events.push_back(event);
+    return events;
+}
+
+AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Accel Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::ACCELEROMETER;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 78.4f;  // +/- 8g
+    mSensorInfo.resolution = 1.52e-5;
+    mSensorInfo.power = 0.001f;          // mA
+    mSensorInfo.minDelay = 20 * 1000;    // microseconds
+    mSensorInfo.maxDelay = 1000 * 1000;  // microseconds
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
diff --git a/sensors/2.0/default/Sensor.h b/sensors/2.0/default/Sensor.h
new file mode 100644
index 0000000..75d9aab
--- /dev/null
+++ b/sensors/2.0/default/Sensor.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_SENSORS_V2_0_SENSOR_H
+#define ANDROID_HARDWARE_SENSORS_V2_0_SENSOR_H
+
+#include <android/hardware/sensors/1.0/types.h>
+
+#include <condition_variable>
+#include <memory>
+#include <thread>
+#include <vector>
+
+using ::android::hardware::sensors::V1_0::Event;
+using ::android::hardware::sensors::V1_0::Result;
+using ::android::hardware::sensors::V1_0::SensorInfo;
+using ::android::hardware::sensors::V1_0::SensorType;
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_0 {
+namespace implementation {
+
+class ISensorsEventCallback {
+   public:
+    virtual ~ISensorsEventCallback(){};
+    virtual void postEvents(const std::vector<Event>& events) = 0;
+};
+
+class Sensor {
+   public:
+    Sensor(ISensorsEventCallback* callback);
+    virtual ~Sensor();
+
+    const SensorInfo& getSensorInfo() const;
+    void batch(int32_t samplingPeriodNs);
+    void activate(bool enable);
+    Result flush();
+
+   protected:
+    void run();
+    virtual std::vector<Event> readEvents();
+    static void startThread(Sensor* sensor);
+
+    bool mIsEnabled;
+    int64_t mSamplingPeriodNs;
+    int64_t mLastSampleTimeNs;
+    SensorInfo mSensorInfo;
+
+    std::atomic_bool mStopThread;
+    std::condition_variable mWaitCV;
+    std::thread mRunThread;
+
+    ISensorsEventCallback* mCallback;
+};
+
+class AccelSensor : public Sensor {
+   public:
+    AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_SENSORS_V2_0_SENSOR_H
diff --git a/sensors/2.0/default/Sensors.cpp b/sensors/2.0/default/Sensors.cpp
new file mode 100644
index 0000000..cceb7d5
--- /dev/null
+++ b/sensors/2.0/default/Sensors.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2018 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 "Sensors.h"
+
+#include <android/hardware/sensors/2.0/types.h>
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::sensors::V1_0::Event;
+using ::android::hardware::sensors::V1_0::OperationMode;
+using ::android::hardware::sensors::V1_0::RateLevel;
+using ::android::hardware::sensors::V1_0::Result;
+using ::android::hardware::sensors::V1_0::SharedMemInfo;
+
+Sensors::Sensors() : mEventQueueFlag(nullptr) {
+    std::shared_ptr<AccelSensor> accel =
+        std::make_shared<AccelSensor>(1 /* sensorHandle */, this /* callback */);
+    mSensors[accel->getSensorInfo().sensorHandle] = accel;
+}
+
+Sensors::~Sensors() {
+    deleteEventFlag();
+}
+
+// Methods from ::android::hardware::sensors::V2_0::ISensors follow.
+Return<void> Sensors::getSensorsList(getSensorsList_cb _hidl_cb) {
+    std::vector<SensorInfo> sensors;
+    for (const auto& sensor : mSensors) {
+        sensors.push_back(sensor.second->getSensorInfo());
+    }
+
+    // Call the HIDL callback with the SensorInfo
+    _hidl_cb(sensors);
+
+    return Void();
+}
+
+Return<Result> Sensors::setOperationMode(OperationMode /* mode */) {
+    // TODO implement
+    return Result{};
+}
+
+Return<Result> Sensors::activate(int32_t sensorHandle, bool enabled) {
+    auto sensor = mSensors.find(sensorHandle);
+    if (sensor != mSensors.end()) {
+        sensor->second->activate(enabled);
+        return Result::OK;
+    }
+    return Result::BAD_VALUE;
+}
+
+Return<Result> Sensors::initialize(
+    const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
+    const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
+    const sp<ISensorsCallback>& sensorsCallback) {
+    Result result = Result::OK;
+
+    // Save a reference to the callback
+    mCallback = sensorsCallback;
+
+    // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
+    mEventQueue =
+        std::make_unique<EventMessageQueue>(eventQueueDescriptor, true /* resetPointers */);
+
+    // Ensure that any existing EventFlag is properly deleted
+    deleteEventFlag();
+
+    // Create the EventFlag that is used to signal to the framework that sensor events have been
+    // written to the Event FMQ
+    if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
+        result = Result::BAD_VALUE;
+    }
+
+    // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
+    // events have been successfully read and handled by the framework.
+    mWakeLockQueue =
+        std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
+
+    if (!mCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
+        result = Result::BAD_VALUE;
+    }
+
+    return result;
+}
+
+Return<Result> Sensors::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
+                              int64_t /* maxReportLatencyNs */) {
+    auto sensor = mSensors.find(sensorHandle);
+    if (sensor != mSensors.end()) {
+        sensor->second->batch(samplingPeriodNs);
+        return Result::OK;
+    }
+    return Result::BAD_VALUE;
+}
+
+Return<Result> Sensors::flush(int32_t sensorHandle) {
+    auto sensor = mSensors.find(sensorHandle);
+    if (sensor != mSensors.end()) {
+        return sensor->second->flush();
+    }
+    return Result::BAD_VALUE;
+}
+
+Return<Result> Sensors::injectSensorData(const Event& /* event */) {
+    // TODO implement
+    return Result{};
+}
+
+Return<void> Sensors::registerDirectChannel(const SharedMemInfo& /* mem */,
+                                            registerDirectChannel_cb _hidl_cb) {
+    _hidl_cb(Result::INVALID_OPERATION, 0 /* channelHandle */);
+    return Return<void>();
+}
+
+Return<Result> Sensors::unregisterDirectChannel(int32_t /* channelHandle */) {
+    return Result::INVALID_OPERATION;
+}
+
+Return<void> Sensors::configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */,
+                                         RateLevel /* rate */, configDirectReport_cb _hidl_cb) {
+    _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */);
+    return Return<void>();
+}
+
+void Sensors::postEvents(const std::vector<Event>& events) {
+    std::lock_guard<std::mutex> l(mLock);
+
+    // TODO: read events from the Wake Lock FMQ in the right place
+    std::vector<uint32_t> tmp(mWakeLockQueue->availableToRead());
+    mWakeLockQueue->read(tmp.data(), mWakeLockQueue->availableToRead());
+
+    mEventQueue->write(events.data(), events.size());
+    mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
+}
+
+void Sensors::deleteEventFlag() {
+    status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag);
+    if (status != OK) {
+        ALOGI("Failed to delete event flag: %d", status);
+    }
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
diff --git a/sensors/2.0/default/Sensors.h b/sensors/2.0/default/Sensors.h
new file mode 100644
index 0000000..f543935
--- /dev/null
+++ b/sensors/2.0/default/Sensors.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_SENSORS_V2_0_SENSORS_H
+#define ANDROID_HARDWARE_SENSORS_V2_0_SENSORS_H
+
+#include "Sensor.h"
+
+#include <android/hardware/sensors/2.0/ISensors.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <memory>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::EventFlag;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptor;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct Sensors : public ISensors, public ISensorsEventCallback {
+    using Event = ::android::hardware::sensors::V1_0::Event;
+    using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
+    using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
+    using Result = ::android::hardware::sensors::V1_0::Result;
+    using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
+
+    Sensors();
+    virtual ~Sensors();
+
+    // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
+    Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
+
+    Return<Result> setOperationMode(OperationMode mode) override;
+
+    Return<Result> activate(int32_t sensorHandle, bool enabled) override;
+
+    Return<Result> initialize(
+        const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
+        const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
+        const sp<ISensorsCallback>& sensorsCallback) override;
+
+    Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
+                         int64_t maxReportLatencyNs) override;
+
+    Return<Result> flush(int32_t sensorHandle) override;
+
+    Return<Result> injectSensorData(const Event& event) override;
+
+    Return<void> registerDirectChannel(const SharedMemInfo& mem,
+                                       registerDirectChannel_cb _hidl_cb) override;
+
+    Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
+
+    Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
+                                    configDirectReport_cb _hidl_cb) override;
+
+    void postEvents(const std::vector<Event>& events) override;
+
+   private:
+    /**
+     * Utility function to delete the Event Flag
+     */
+    void deleteEventFlag();
+
+    using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
+    using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
+
+    /**
+     * The Event FMQ where sensor events are written
+     */
+    std::unique_ptr<EventMessageQueue> mEventQueue;
+
+    /**
+     * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events
+     */
+    std::unique_ptr<WakeLockMessageQueue> mWakeLockQueue;
+
+    /**
+     * Event Flag to signal to the framework when sensor events are available to be read
+     */
+    EventFlag* mEventQueueFlag;
+
+    /**
+     * Callback for asynchronous events, such as dynamic sensor connections.
+     */
+    sp<ISensorsCallback> mCallback;
+
+    /**
+     * A map of the available sensors
+     */
+    std::map<int32_t, std::shared_ptr<Sensor>> mSensors;
+
+    /**
+     * Lock to protect writes and reads to the FMQs
+     */
+    std::mutex mLock;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_SENSORS_V2_0_SENSORS_H
diff --git a/sensors/2.0/default/android.hardware.sensors@2.0-service.rc b/sensors/2.0/default/android.hardware.sensors@2.0-service.rc
new file mode 100644
index 0000000..321d760
--- /dev/null
+++ b/sensors/2.0/default/android.hardware.sensors@2.0-service.rc
@@ -0,0 +1,5 @@
+service vendor.sensors-hal-2-0 /vendor/bin/hw/android.hardware.sensors@2.0-service
+    class hal
+    user system
+    group system
+    rlimit rtprio 10 10
diff --git a/sensors/2.0/default/service.cpp b/sensors/2.0/default/service.cpp
new file mode 100644
index 0000000..5c13e33
--- /dev/null
+++ b/sensors/2.0/default/service.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.sensors@2.0-service"
+
+#include <android/hardware/sensors/2.0/ISensors.h>
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+#include <utils/StrongPointer.h>
+#include "Sensors.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::sensors::V2_0::ISensors;
+using android::hardware::sensors::V2_0::implementation::Sensors;
+
+int main(int /* argc */, char** /* argv */) {
+    configureRpcThreadpool(1, true);
+
+    android::sp<ISensors> sensors = new Sensors();
+    if (sensors->registerAsService() != ::android::OK) {
+        ALOGE("Failed to register Sensors HAL instance");
+        return -1;
+    }
+
+    joinRpcThreadpool();
+    return 1;  // joinRpcThreadpool shouldn't exit
+}
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
index 5444287..37b7349 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
@@ -95,19 +95,19 @@
 }
 
 void SensorsHidlEnvironmentV2_0::HidlTearDown() {
-    stopThread = true;
+    mStopThread = true;
 
     // Wake up the event queue so the poll thread can exit
     mEventQueueFlag->wake(asBaseType(EventQueueFlagBits::READ_AND_PROCESS));
-    pollThread.join();
+    mPollThread.join();
 
     EventFlag::deleteEventFlag(&mEventQueueFlag);
 }
 
 void SensorsHidlEnvironmentV2_0::startPollingThread() {
-    stopThread = false;
-    pollThread = std::thread(pollingThread, this);
-    events.reserve(MAX_RECEIVE_BUFFER_EVENT_COUNT);
+    mStopThread = false;
+    mPollThread = std::thread(pollingThread, this);
+    mEvents.reserve(MAX_RECEIVE_BUFFER_EVENT_COUNT);
 }
 
 void SensorsHidlEnvironmentV2_0::readEvents() {
@@ -123,8 +123,8 @@
     size_t eventsToRead = std::min(availableEvents, mEventBuffer.size());
     if (eventsToRead > 0) {
         if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
-            for (const auto& e : mEventBuffer) {
-                addEvent(e);
+            for (size_t i = 0; i < eventsToRead; i++) {
+                addEvent(mEventBuffer[i]);
             }
         }
     }
@@ -133,7 +133,7 @@
 void SensorsHidlEnvironmentV2_0::pollingThread(SensorsHidlEnvironmentV2_0* env) {
     ALOGD("polling thread start");
 
-    while (!env->stopThread.load()) {
+    while (!env->mStopThread.load()) {
         env->readEvents();
     }
 
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
index 7241923..5e54530 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
@@ -47,7 +47,7 @@
 
     virtual void HidlTearDown() override;
 
-   private:
+   protected:
     friend SensorsHidlTest;
 
     SensorsHidlEnvironmentV2_0() : mEventQueueFlag(nullptr) {}
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index 7c6f010..3e5837b 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -25,15 +25,89 @@
 #include <utils/SystemClock.h>
 
 #include <cinttypes>
+#include <condition_variable>
+#include <map>
 #include <vector>
 
 using ::android::sp;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hardware::sensors::V1_0::MetaDataEventType;
 using ::android::hardware::sensors::V1_0::OperationMode;
 using ::android::hardware::sensors::V1_0::SensorStatus;
 using ::android::hardware::sensors::V1_0::Vec3;
 
+class EventCallback : public IEventCallback {
+   public:
+    void reset() {
+        mFlushMap.clear();
+        mEventMap.clear();
+    }
+
+    void onEvent(const ::android::hardware::sensors::V1_0::Event& event) override {
+        if (event.sensorType == SensorType::ADDITIONAL_INFO &&
+            event.u.meta.what == MetaDataEventType::META_DATA_FLUSH_COMPLETE) {
+            std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
+            mFlushMap[event.sensorHandle]++;
+            mFlushCV.notify_all();
+        } else if (event.sensorType != SensorType::ADDITIONAL_INFO) {
+            std::unique_lock<std::recursive_mutex> lock(mEventMutex);
+            mEventMap[event.sensorHandle].push_back(event);
+            mEventCV.notify_all();
+        }
+    }
+
+    int32_t getFlushCount(int32_t sensorHandle) {
+        std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
+        return mFlushMap[sensorHandle];
+    }
+
+    void waitForFlushEvents(const std::vector<SensorInfo>& sensorsToWaitFor,
+                            int32_t numCallsToFlush, int64_t timeoutMs) {
+        std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
+        mFlushCV.wait_for(lock, std::chrono::milliseconds(timeoutMs),
+                          [&] { return flushesReceived(sensorsToWaitFor, numCallsToFlush); });
+    }
+
+    const std::vector<Event> getEvents(int32_t sensorHandle) {
+        std::unique_lock<std::recursive_mutex> lock(mEventMutex);
+        return mEventMap[sensorHandle];
+    }
+
+    void waitForEvents(const std::vector<SensorInfo>& sensorsToWaitFor, int32_t timeoutMs) {
+        std::unique_lock<std::recursive_mutex> lock(mEventMutex);
+        mEventCV.wait_for(lock, std::chrono::milliseconds(timeoutMs),
+                          [&] { return eventsReceived(sensorsToWaitFor); });
+    }
+
+   protected:
+    bool flushesReceived(const std::vector<SensorInfo>& sensorsToWaitFor, int32_t numCallsToFlush) {
+        for (const SensorInfo& sensor : sensorsToWaitFor) {
+            if (getFlushCount(sensor.sensorHandle) < numCallsToFlush) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    bool eventsReceived(const std::vector<SensorInfo>& sensorsToWaitFor) {
+        for (const SensorInfo& sensor : sensorsToWaitFor) {
+            if (getEvents(sensor.sensorHandle).size() == 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    std::map<int32_t, int32_t> mFlushMap;
+    std::recursive_mutex mFlushMutex;
+    std::condition_variable_any mFlushCV;
+
+    std::map<int32_t, std::vector<Event>> mEventMap;
+    std::recursive_mutex mEventMutex;
+    std::condition_variable_any mEventCV;
+};
+
 // The main test class for SENSORS HIDL HAL.
 
 class SensorsHidlTest : public SensorsHidlTestBase {
@@ -79,6 +153,18 @@
     SensorsHidlEnvironmentBase* getEnvironment() override {
         return SensorsHidlEnvironmentV2_0::Instance();
     }
+
+    // Test helpers
+    void runSingleFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
+                            int32_t expectedFlushCount, Result expectedResponse);
+    void runFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
+                      int32_t flushCalls, int32_t expectedFlushCount, Result expectedResponse);
+
+    // Helper functions
+    void activateAllSensors(bool enable);
+    std::vector<SensorInfo> getNonOneShotSensors();
+    std::vector<SensorInfo> getOneShotSensors();
+    int32_t getInvalidSensorHandle();
 };
 
 Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
@@ -137,6 +223,35 @@
     return ret;
 }
 
+std::vector<SensorInfo> SensorsHidlTest::getNonOneShotSensors() {
+    std::vector<SensorInfo> sensors;
+    for (const SensorInfo& info : getSensorsList()) {
+        if (extractReportMode(info.flags) != SensorFlagBits::ONE_SHOT_MODE) {
+            sensors.push_back(info);
+        }
+    }
+    return sensors;
+}
+
+std::vector<SensorInfo> SensorsHidlTest::getOneShotSensors() {
+    std::vector<SensorInfo> sensors;
+    for (const SensorInfo& info : getSensorsList()) {
+        if (extractReportMode(info.flags) == SensorFlagBits::ONE_SHOT_MODE) {
+            sensors.push_back(info);
+        }
+    }
+    return sensors;
+}
+
+int32_t SensorsHidlTest::getInvalidSensorHandle() {
+    // Find a sensor handle that does not exist in the sensor list
+    int32_t maxHandle = 0;
+    for (const SensorInfo& sensor : getSensorsList()) {
+        maxHandle = max(maxHandle, sensor.sensorHandle);
+    }
+    return maxHandle + 1;
+}
+
 // Test if sensor list returned is valid
 TEST_F(SensorsHidlTest, SensorListValid) {
     getSensors()->getSensorsList([&](const auto& list) {
@@ -437,6 +552,243 @@
                               RateLevel::VERY_FAST, NullChecker());
 }
 
+void SensorsHidlTest::activateAllSensors(bool enable) {
+    for (const SensorInfo& sensorInfo : getSensorsList()) {
+        if (isValidType(sensorInfo.type)) {
+            batch(sensorInfo.sensorHandle, sensorInfo.minDelay, 0 /* maxReportLatencyNs */);
+            activate(sensorInfo.sensorHandle, enable);
+        }
+    }
+}
+
+// Test that if initialize is called twice, then the HAL writes events to the FMQs from the second
+// call to the function.
+TEST_F(SensorsHidlTest, CallInitializeTwice) {
+    // Create a helper class so that a second environment is able to be instantiated
+    class SensorsHidlEnvironmentTest : public SensorsHidlEnvironmentV2_0 {};
+
+    if (getSensorsList().size() == 0) {
+        // No sensors
+        return;
+    }
+
+    constexpr useconds_t kCollectionTimeoutUs = 1000 * 1000;  // 1s
+    constexpr int32_t kNumEvents = 1;
+
+    // Create a new environment that calls initialize()
+    std::unique_ptr<SensorsHidlEnvironmentTest> newEnv =
+        std::make_unique<SensorsHidlEnvironmentTest>();
+    newEnv->HidlSetUp();
+
+    activateAllSensors(true);
+    // Verify that the old environment does not receive any events
+    ASSERT_EQ(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), 0);
+    // Verify that the new event queue receives sensor events
+    ASSERT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents, newEnv.get()).size(), kNumEvents);
+    activateAllSensors(false);
+
+    // Cleanup the test environment
+    newEnv->HidlTearDown();
+
+    // Restore the test environment for future tests
+    SensorsHidlEnvironmentV2_0::Instance()->HidlTearDown();
+    SensorsHidlEnvironmentV2_0::Instance()->HidlSetUp();
+
+    // Ensure that the original environment is receiving events
+    activateAllSensors(true);
+    ASSERT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
+    activateAllSensors(false);
+}
+
+void SensorsHidlTest::runSingleFlushTest(const std::vector<SensorInfo>& sensors,
+                                         bool activateSensor, int32_t expectedFlushCount,
+                                         Result expectedResponse) {
+    runFlushTest(sensors, activateSensor, 1 /* flushCalls */, expectedFlushCount, expectedResponse);
+}
+
+void SensorsHidlTest::runFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
+                                   int32_t flushCalls, int32_t expectedFlushCount,
+                                   Result expectedResponse) {
+    EventCallback callback;
+    getEnvironment()->registerCallback(&callback);
+
+    for (const SensorInfo& sensor : sensors) {
+        // Configure and activate the sensor
+        batch(sensor.sensorHandle, sensor.maxDelay, 0 /* maxReportLatencyNs */);
+        activate(sensor.sensorHandle, activateSensor);
+
+        // Flush the sensor
+        for (int32_t i = 0; i < flushCalls; i++) {
+            Result flushResult = flush(sensor.sensorHandle);
+            ASSERT_EQ(flushResult, expectedResponse);
+        }
+        activate(sensor.sensorHandle, false);
+    }
+
+    // Wait up to one second for the flush events
+    callback.waitForFlushEvents(sensors, flushCalls, 1000 /* timeoutMs */);
+    getEnvironment()->unregisterCallback();
+
+    // Check that the correct number of flushes are present for each sensor
+    for (const SensorInfo& sensor : sensors) {
+        ASSERT_EQ(callback.getFlushCount(sensor.sensorHandle), expectedFlushCount);
+    }
+}
+
+TEST_F(SensorsHidlTest, FlushSensor) {
+    // Find a sensor that is not a one-shot sensor
+    std::vector<SensorInfo> sensors = getNonOneShotSensors();
+    if (sensors.size() == 0) {
+        return;
+    }
+
+    constexpr int32_t kFlushes = 5;
+    runSingleFlushTest(sensors, true /* activateSensor */, 1 /* expectedFlushCount */, Result::OK);
+    runFlushTest(sensors, true /* activateSensor */, kFlushes, kFlushes, Result::OK);
+}
+
+TEST_F(SensorsHidlTest, FlushOneShotSensor) {
+    // Find a sensor that is a one-shot sensor
+    std::vector<SensorInfo> sensors = getOneShotSensors();
+    if (sensors.size() == 0) {
+        return;
+    }
+
+    runSingleFlushTest(sensors, true /* activateSensor */, 0 /* expectedFlushCount */,
+                       Result::BAD_VALUE);
+}
+
+TEST_F(SensorsHidlTest, FlushInactiveSensor) {
+    // Attempt to find a non-one shot sensor, then a one-shot sensor if necessary
+    std::vector<SensorInfo> sensors = getNonOneShotSensors();
+    if (sensors.size() == 0) {
+        sensors = getOneShotSensors();
+        if (sensors.size() == 0) {
+            return;
+        }
+    }
+
+    runSingleFlushTest(sensors, false /* activateSensor */, 0 /* expectedFlushCount */,
+                       Result::BAD_VALUE);
+}
+
+TEST_F(SensorsHidlTest, FlushNonexistentSensor) {
+    SensorInfo sensor;
+    std::vector<SensorInfo> sensors = getNonOneShotSensors();
+    if (sensors.size() == 0) {
+        sensors = getOneShotSensors();
+        if (sensors.size() == 0) {
+            return;
+        }
+    }
+    sensor = sensors.front();
+    sensor.sensorHandle = getInvalidSensorHandle();
+    runSingleFlushTest(std::vector<SensorInfo>{sensor}, false /* activateSensor */,
+                       0 /* expectedFlushCount */, Result::BAD_VALUE);
+}
+
+TEST_F(SensorsHidlTest, Batch) {
+    if (getSensorsList().size() == 0) {
+        return;
+    }
+
+    activateAllSensors(false /* enable */);
+    for (const SensorInfo& sensor : getSensorsList()) {
+        // Call batch on inactive sensor
+        ASSERT_EQ(batch(sensor.sensorHandle, sensor.minDelay, 0 /* maxReportLatencyNs */),
+                  Result::OK);
+
+        // Activate the sensor
+        activate(sensor.sensorHandle, true /* enabled */);
+
+        // Call batch on an active sensor
+        ASSERT_EQ(batch(sensor.sensorHandle, sensor.maxDelay, 0 /* maxReportLatencyNs */),
+                  Result::OK);
+    }
+    activateAllSensors(false /* enable */);
+
+    // Call batch on an invalid sensor
+    SensorInfo sensor = getSensorsList().front();
+    sensor.sensorHandle = getInvalidSensorHandle();
+    ASSERT_EQ(batch(sensor.sensorHandle, sensor.minDelay, 0 /* maxReportLatencyNs */),
+              Result::BAD_VALUE);
+}
+
+TEST_F(SensorsHidlTest, Activate) {
+    if (getSensorsList().size() == 0) {
+        return;
+    }
+
+    // Verify that sensor events are generated when activate is called
+    for (const SensorInfo& sensor : getSensorsList()) {
+        batch(sensor.sensorHandle, sensor.minDelay, 0 /* maxReportLatencyNs */);
+        ASSERT_EQ(activate(sensor.sensorHandle, true), Result::OK);
+
+        // Call activate on a sensor that is already activated
+        ASSERT_EQ(activate(sensor.sensorHandle, true), Result::OK);
+
+        // Deactivate the sensor
+        ASSERT_EQ(activate(sensor.sensorHandle, false), Result::OK);
+
+        // Call deactivate on a sensor that is already deactivated
+        ASSERT_EQ(activate(sensor.sensorHandle, false), Result::OK);
+    }
+
+    // Attempt to activate an invalid sensor
+    int32_t invalidHandle = getInvalidSensorHandle();
+    ASSERT_EQ(activate(invalidHandle, true), Result::BAD_VALUE);
+    ASSERT_EQ(activate(invalidHandle, false), Result::BAD_VALUE);
+}
+
+TEST_F(SensorsHidlTest, NoStaleEvents) {
+    constexpr int64_t kFiveHundredMilliseconds = 500 * 1000;
+    constexpr int64_t kOneSecond = 1000 * 1000;
+
+    // Register the callback to receive sensor events
+    EventCallback callback;
+    getEnvironment()->registerCallback(&callback);
+
+    const std::vector<SensorInfo> sensors = getSensorsList();
+    int32_t maxMinDelay = 0;
+    for (const SensorInfo& sensor : getSensorsList()) {
+        maxMinDelay = std::max(maxMinDelay, sensor.minDelay);
+    }
+
+    // Activate the sensors so that they start generating events
+    activateAllSensors(true);
+
+    // According to the CDD, the first sample must be generated within 400ms + 2 * sample_time
+    // and the maximum reporting latency is 100ms + 2 * sample_time. Wait a sufficient amount
+    // of time to guarantee that a sample has arrived.
+    callback.waitForEvents(sensors, kFiveHundredMilliseconds + (5 * maxMinDelay));
+    activateAllSensors(false);
+
+    // Save the last received event for each sensor
+    std::map<int32_t, int64_t> lastEventTimestampMap;
+    for (const SensorInfo& sensor : sensors) {
+        ASSERT_GE(callback.getEvents(sensor.sensorHandle).size(), 1);
+        lastEventTimestampMap[sensor.sensorHandle] =
+            callback.getEvents(sensor.sensorHandle).back().timestamp;
+    }
+
+    // Allow some time to pass, reset the callback, then reactivate the sensors
+    usleep(kOneSecond + (5 * maxMinDelay));
+    callback.reset();
+    activateAllSensors(true);
+    callback.waitForEvents(sensors, kFiveHundredMilliseconds + (5 * maxMinDelay));
+    activateAllSensors(false);
+
+    for (const SensorInfo& sensor : sensors) {
+        // Ensure that the first event received is not stale by ensuring that its timestamp is
+        // sufficiently different from the previous event
+        const Event newEvent = callback.getEvents(sensor.sensorHandle).front();
+        int64_t delta = newEvent.timestamp - lastEventTimestampMap[sensor.sensorHandle];
+        ASSERT_GE(delta, kFiveHundredMilliseconds + (3 * sensor.minDelay));
+    }
+
+    getEnvironment()->unregisterCallback();
+}
+
 int main(int argc, char** argv) {
     ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironmentV2_0::Instance());
     ::testing::InitGoogleTest(&argc, argv);
diff --git a/sensors/common/vts/utils/SensorsHidlEnvironmentBase.cpp b/sensors/common/vts/utils/SensorsHidlEnvironmentBase.cpp
index 21c08d2..affdf8b 100644
--- a/sensors/common/vts/utils/SensorsHidlEnvironmentBase.cpp
+++ b/sensors/common/vts/utils/SensorsHidlEnvironmentBase.cpp
@@ -19,7 +19,7 @@
 void SensorsHidlEnvironmentBase::HidlSetUp() {
     ASSERT_TRUE(resetHal()) << "could not get hidl service";
 
-    collectionEnabled = false;
+    mCollectionEnabled = false;
     startPollingThread();
 
     // In case framework just stopped for test and there is sensor events in the pipe,
@@ -28,26 +28,40 @@
 }
 
 void SensorsHidlEnvironmentBase::HidlTearDown() {
-    stopThread = true;
-    pollThread.detach();
+    mStopThread = true;
+    mPollThread.detach();
 }
 
 void SensorsHidlEnvironmentBase::catEvents(std::vector<Event>* output) {
-    std::lock_guard<std::mutex> lock(events_mutex);
+    std::lock_guard<std::mutex> lock(mEventsMutex);
     if (output) {
-        output->insert(output->end(), events.begin(), events.end());
+        output->insert(output->end(), mEvents.begin(), mEvents.end());
     }
-    events.clear();
+    mEvents.clear();
 }
 
 void SensorsHidlEnvironmentBase::setCollection(bool enable) {
-    std::lock_guard<std::mutex> lock(events_mutex);
-    collectionEnabled = enable;
+    std::lock_guard<std::mutex> lock(mEventsMutex);
+    mCollectionEnabled = enable;
 }
 
 void SensorsHidlEnvironmentBase::addEvent(const Event& ev) {
-    std::lock_guard<std::mutex> lock(events_mutex);
-    if (collectionEnabled) {
-        events.push_back(ev);
+    std::lock_guard<std::mutex> lock(mEventsMutex);
+    if (mCollectionEnabled) {
+        mEvents.push_back(ev);
+    }
+
+    if (mCallback != nullptr) {
+        mCallback->onEvent(ev);
     }
 }
+
+void SensorsHidlEnvironmentBase::registerCallback(IEventCallback* callback) {
+    std::lock_guard<std::mutex> lock(mEventsMutex);
+    mCallback = callback;
+}
+
+void SensorsHidlEnvironmentBase::unregisterCallback() {
+    std::lock_guard<std::mutex> lock(mEventsMutex);
+    mCallback = nullptr;
+}
\ No newline at end of file
diff --git a/sensors/common/vts/utils/SensorsHidlTestBase.cpp b/sensors/common/vts/utils/SensorsHidlTestBase.cpp
index b72fdfd..18549df 100644
--- a/sensors/common/vts/utils/SensorsHidlTestBase.cpp
+++ b/sensors/common/vts/utils/SensorsHidlTestBase.cpp
@@ -40,6 +40,14 @@
 std::vector<Event> SensorsHidlTestBase::collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
                                                       bool clearBeforeStart,
                                                       bool changeCollection) {
+    return collectEvents(timeLimitUs, nEventLimit, getEnvironment(), clearBeforeStart,
+                         changeCollection);
+}
+
+std::vector<Event> SensorsHidlTestBase::collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
+                                                      SensorsHidlEnvironmentBase* environment,
+                                                      bool clearBeforeStart,
+                                                      bool changeCollection) {
     std::vector<Event> events;
     constexpr useconds_t SLEEP_GRANULARITY = 100 * 1000;  // granularity 100 ms
 
@@ -47,10 +55,10 @@
           clearBeforeStart);
 
     if (changeCollection) {
-        getEnvironment()->setCollection(true);
+        environment->setCollection(true);
     }
     if (clearBeforeStart) {
-        getEnvironment()->catEvents(nullptr);
+        environment->catEvents(nullptr);
     }
 
     while (timeLimitUs > 0) {
@@ -58,7 +66,7 @@
         usleep(duration);
         timeLimitUs -= duration;
 
-        getEnvironment()->catEvents(&events);
+        environment->catEvents(&events);
         if (events.size() >= nEventLimit) {
             break;
         }
@@ -67,7 +75,7 @@
     }
 
     if (changeCollection) {
-        getEnvironment()->setCollection(false);
+        environment->setCollection(false);
     }
     return events;
 }
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
index 96e6085..6499fba 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
@@ -27,6 +27,12 @@
 #include <thread>
 #include <vector>
 
+class IEventCallback {
+   public:
+    virtual ~IEventCallback() = default;
+    virtual void onEvent(const ::android::hardware::sensors::V1_0::Event& event) = 0;
+};
+
 class SensorsHidlEnvironmentBase : public ::testing::VtsHalHidlTargetTestEnvBase {
    public:
     using Event = ::android::hardware::sensors::V1_0::Event;
@@ -40,19 +46,24 @@
     // set sensor event collection status
     void setCollection(bool enable);
 
+    void registerCallback(IEventCallback* callback);
+    void unregisterCallback();
+
    protected:
-    SensorsHidlEnvironmentBase() {}
+    SensorsHidlEnvironmentBase() : mCollectionEnabled(false), mCallback(nullptr) {}
 
     void addEvent(const Event& ev);
 
     virtual void startPollingThread() = 0;
     virtual bool resetHal() = 0;
 
-    bool collectionEnabled;
-    std::atomic_bool stopThread;
-    std::thread pollThread;
-    std::vector<Event> events;
-    std::mutex events_mutex;
+    bool mCollectionEnabled;
+    std::atomic_bool mStopThread;
+    std::thread mPollThread;
+    std::vector<Event> mEvents;
+    std::mutex mEventsMutex;
+
+    IEventCallback* mCallback;
 
     GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentBase);
 };
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
index f4b259f..6fd9a2b 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
@@ -85,6 +85,10 @@
 
     std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
                                      bool clearBeforeStart = true, bool changeCollection = true);
+    static std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
+                                            SensorsHidlEnvironmentBase* environment,
+                                            bool clearBeforeStart = true,
+                                            bool changeCollection = true);
 
     inline static SensorFlagBits extractReportMode(uint64_t flag) {
         return (SensorFlagBits)(flag & ((uint64_t)SensorFlagBits::CONTINUOUS_MODE |
diff --git a/soundtrigger/2.2/Android.bp b/soundtrigger/2.2/Android.bp
new file mode 100644
index 0000000..0a7c2d8
--- /dev/null
+++ b/soundtrigger/2.2/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.soundtrigger@2.2",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "ISoundTriggerHw.hal",
+    ],
+    interfaces: [
+        "android.hardware.audio.common@2.0",
+        "android.hardware.soundtrigger@2.0",
+        "android.hardware.soundtrigger@2.1",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: false,
+}
+
diff --git a/soundtrigger/2.2/ISoundTriggerHw.hal b/soundtrigger/2.2/ISoundTriggerHw.hal
new file mode 100644
index 0000000..fcb5087
--- /dev/null
+++ b/soundtrigger/2.2/ISoundTriggerHw.hal
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2018 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.soundtrigger@2.2;
+
+import @2.0::ISoundTriggerHwCallback.RecognitionEvent;
+import @2.0::SoundModelHandle;
+import @2.1::ISoundTriggerHw;
+
+/**
+ * SoundTrigger HAL interface. Used for hardware recognition of hotwords.
+ */
+interface ISoundTriggerHw extends @2.1::ISoundTriggerHw {
+
+    /**
+     * Get the state of a given model.
+     * The model state is returned as a RecognitionEvent.
+     * @param modelHandle The handle of the sound model to use for recognition
+     * @return retval Operation completion status: 0 in case of success,
+     *                -ENOSYS in case of invalid model handle,
+     *                -ENOMEM in case of memory allocation failure,
+     *                -ENODEV in case of initialization error.
+     * @return state  RecognitionEvent in case of success
+     */
+    getModelState(SoundModelHandle modelHandle)
+            generates (int32_t retval, @2.0::ISoundTriggerHwCallback.RecognitionEvent state);
+};
diff --git a/soundtrigger/2.2/default/Android.bp b/soundtrigger/2.2/default/Android.bp
new file mode 100644
index 0000000..78bb69f
--- /dev/null
+++ b/soundtrigger/2.2/default/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "android.hardware.soundtrigger@2.2-impl",
+    relative_install_path: "hw",
+    vendor: true,
+    srcs: [
+        "SoundTriggerHw.cpp",
+    ],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libhidlmemory",
+        "libutils",
+        "libhardware",
+        "android.hardware.soundtrigger@2.0",
+        "android.hardware.soundtrigger@2.0-core",
+        "android.hardware.soundtrigger@2.1",
+        "android.hardware.soundtrigger@2.2",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+    ],
+}
diff --git a/soundtrigger/2.2/default/SoundTriggerHw.cpp b/soundtrigger/2.2/default/SoundTriggerHw.cpp
new file mode 100644
index 0000000..ffdf9fb
--- /dev/null
+++ b/soundtrigger/2.2/default/SoundTriggerHw.cpp
@@ -0,0 +1,744 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SoundTriggerHw"
+
+#include "SoundTriggerHw.h"
+
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/log.h>
+#include <hidlmemory/mapping.h>
+#include <utility>
+
+using android::hardware::hidl_memory;
+using android::hidl::allocator::V1_0::IAllocator;
+using android::hidl::memory::V1_0::IMemory;
+
+namespace android {
+namespace hardware {
+namespace soundtrigger {
+namespace V2_2 {
+namespace implementation {
+
+/**
+ * According to the HIDL C++ Users Guide: client and server implementations
+ * should never directly refer to anything other than the interface header
+ * generated from the HIDL definition file (ie. ISoundTriggerHw.hal), so
+ * this V2_2 implementation copies the V2_0 and V2_1 implementations and
+ * then adds the new V2_2 implementation.
+ */
+
+// Begin V2_0 implementation, copied from
+// hardware/interfaces/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp
+
+// static
+void soundModelCallback_(struct sound_trigger_model_event* halEvent, void* cookie) {
+    if (halEvent == NULL) {
+        ALOGW("soundModelCallback called with NULL event");
+        return;
+    }
+    sp<SoundTriggerHw::SoundModelClient> client =
+        wp<SoundTriggerHw::SoundModelClient>(static_cast<SoundTriggerHw::SoundModelClient*>(cookie))
+            .promote();
+    if (client == 0) {
+        ALOGW("soundModelCallback called on stale client");
+        return;
+    }
+    if (halEvent->model != client->getHalHandle()) {
+        ALOGW("soundModelCallback call with wrong handle %d on client with handle %d",
+              (int)halEvent->model, (int)client->getHalHandle());
+        return;
+    }
+
+    client->soundModelCallback(halEvent);
+}
+
+// static
+void recognitionCallback_(struct sound_trigger_recognition_event* halEvent, void* cookie) {
+    if (halEvent == NULL) {
+        ALOGW("recognitionCallback call NULL event");
+        return;
+    }
+    sp<SoundTriggerHw::SoundModelClient> client =
+        wp<SoundTriggerHw::SoundModelClient>(static_cast<SoundTriggerHw::SoundModelClient*>(cookie))
+            .promote();
+    if (client == 0) {
+        ALOGW("recognitionCallback called on stale client");
+        return;
+    }
+
+    client->recognitionCallback(halEvent);
+}
+
+Return<void> SoundTriggerHw::getProperties(ISoundTriggerHw::getProperties_cb _hidl_cb) {
+    ALOGV("getProperties() mHwDevice %p", mHwDevice);
+    int ret;
+    struct sound_trigger_properties halProperties;
+    ISoundTriggerHw::Properties properties;
+
+    if (mHwDevice == NULL) {
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    ret = mHwDevice->get_properties(mHwDevice, &halProperties);
+
+    convertPropertiesFromHal(&properties, &halProperties);
+
+    ALOGV("getProperties implementor %s recognitionModes %08x", properties.implementor.c_str(),
+          properties.recognitionModes);
+
+exit:
+    _hidl_cb(ret, properties);
+    return Void();
+}
+
+int SoundTriggerHw::doLoadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
+                                     sp<SoundTriggerHw::SoundModelClient> client) {
+    int32_t ret = 0;
+    struct sound_trigger_sound_model* halSoundModel;
+
+    ALOGV("doLoadSoundModel() data size %zu", soundModel.data.size());
+
+    if (mHwDevice == NULL) {
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    halSoundModel = convertSoundModelToHal(&soundModel);
+    if (halSoundModel == NULL) {
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    sound_model_handle_t halHandle;
+    ret = mHwDevice->load_sound_model(mHwDevice, halSoundModel, soundModelCallback_, client.get(),
+                                      &halHandle);
+
+    free(halSoundModel);
+
+    if (ret != 0) {
+        goto exit;
+    }
+
+    client->setHalHandle(halHandle);
+    {
+        AutoMutex lock(mLock);
+        mClients.add(client->getId(), client);
+    }
+
+exit:
+    return ret;
+}
+
+Return<void> SoundTriggerHw::loadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
+                                            const sp<V2_0::ISoundTriggerHwCallback>& callback,
+                                            V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,
+                                            ISoundTriggerHw::loadSoundModel_cb _hidl_cb) {
+    sp<SoundTriggerHw::SoundModelClient> client =
+        new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback);
+    _hidl_cb(doLoadSoundModel(soundModel, client), client->getId());
+    return Void();
+}
+
+Return<void> SoundTriggerHw::loadPhraseSoundModel(
+    const V2_0::ISoundTriggerHw::PhraseSoundModel& soundModel,
+    const sp<V2_0::ISoundTriggerHwCallback>& callback,
+    V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,
+    ISoundTriggerHw::loadPhraseSoundModel_cb _hidl_cb) {
+    sp<SoundTriggerHw::SoundModelClient> client =
+        new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback);
+    _hidl_cb(doLoadSoundModel((const V2_0::ISoundTriggerHw::SoundModel&)soundModel, client),
+             client->getId());
+    return Void();
+}
+
+Return<int32_t> SoundTriggerHw::unloadSoundModel(int32_t modelHandle) {
+    int32_t ret;
+    sp<SoundTriggerHw::SoundModelClient> client;
+
+    if (mHwDevice == NULL) {
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    {
+        AutoMutex lock(mLock);
+        client = mClients.valueFor(modelHandle);
+        if (client == 0) {
+            ret = -ENOSYS;
+            goto exit;
+        }
+    }
+
+    ret = mHwDevice->unload_sound_model(mHwDevice, client->getHalHandle());
+
+    mClients.removeItem(modelHandle);
+
+exit:
+    return ret;
+}
+
+Return<int32_t> SoundTriggerHw::startRecognition(
+    int32_t modelHandle, const V2_0::ISoundTriggerHw::RecognitionConfig& config,
+    const sp<V2_0::ISoundTriggerHwCallback>& /* callback */, int32_t /* cookie */) {
+    int32_t ret;
+    sp<SoundTriggerHw::SoundModelClient> client;
+    struct sound_trigger_recognition_config* halConfig;
+
+    if (mHwDevice == NULL) {
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    {
+        AutoMutex lock(mLock);
+        client = mClients.valueFor(modelHandle);
+        if (client == 0) {
+            ret = -ENOSYS;
+            goto exit;
+        }
+    }
+
+    halConfig =
+        convertRecognitionConfigToHal((const V2_0::ISoundTriggerHw::RecognitionConfig*)&config);
+
+    if (halConfig == NULL) {
+        ret = -EINVAL;
+        goto exit;
+    }
+    ret = mHwDevice->start_recognition(mHwDevice, client->getHalHandle(), halConfig,
+                                       recognitionCallback_, client.get());
+
+    free(halConfig);
+
+exit:
+    return ret;
+}
+
+Return<int32_t> SoundTriggerHw::stopRecognition(int32_t modelHandle) {
+    int32_t ret;
+    sp<SoundTriggerHw::SoundModelClient> client;
+    if (mHwDevice == NULL) {
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    {
+        AutoMutex lock(mLock);
+        client = mClients.valueFor(modelHandle);
+        if (client == 0) {
+            ret = -ENOSYS;
+            goto exit;
+        }
+    }
+
+    ret = mHwDevice->stop_recognition(mHwDevice, client->getHalHandle());
+
+exit:
+    return ret;
+}
+
+Return<int32_t> SoundTriggerHw::stopAllRecognitions() {
+    int32_t ret;
+    if (mHwDevice == NULL) {
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    if (mHwDevice->common.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_1 &&
+        mHwDevice->stop_all_recognitions) {
+        ret = mHwDevice->stop_all_recognitions(mHwDevice);
+    } else {
+        ret = -ENOSYS;
+    }
+exit:
+    return ret;
+}
+
+SoundTriggerHw::SoundTriggerHw() : mModuleName("primary"), mHwDevice(NULL), mNextModelId(1) {}
+
+void SoundTriggerHw::onFirstRef() {
+    const hw_module_t* mod;
+    int rc;
+
+    rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, &mod);
+    if (rc != 0) {
+        ALOGE("couldn't load sound trigger module %s.%s (%s)", SOUND_TRIGGER_HARDWARE_MODULE_ID,
+              mModuleName, strerror(-rc));
+        return;
+    }
+    rc = sound_trigger_hw_device_open(mod, &mHwDevice);
+    if (rc != 0) {
+        ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
+              SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
+        mHwDevice = NULL;
+        return;
+    }
+    if (mHwDevice->common.version < SOUND_TRIGGER_DEVICE_API_VERSION_1_0 ||
+        mHwDevice->common.version > SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
+        ALOGE("wrong sound trigger hw device version %04x", mHwDevice->common.version);
+        sound_trigger_hw_device_close(mHwDevice);
+        mHwDevice = NULL;
+        return;
+    }
+
+    ALOGI("onFirstRef() mModuleName %s mHwDevice %p", mModuleName, mHwDevice);
+}
+
+SoundTriggerHw::~SoundTriggerHw() {
+    if (mHwDevice != NULL) {
+        sound_trigger_hw_device_close(mHwDevice);
+    }
+}
+
+uint32_t SoundTriggerHw::nextUniqueModelId() {
+    uint32_t modelId = 0;
+    {
+        AutoMutex lock(mLock);
+        do {
+            modelId =
+                atomic_fetch_add_explicit(&mNextModelId, (uint_fast32_t)1, memory_order_acq_rel);
+        } while (mClients.valueFor(modelId) != 0 && modelId != 0);
+    }
+    LOG_ALWAYS_FATAL_IF(modelId == 0, "wrap around in sound model IDs, num loaded models %zu",
+                        mClients.size());
+    return modelId;
+}
+
+void SoundTriggerHw::convertUuidFromHal(Uuid* uuid, const sound_trigger_uuid_t* halUuid) {
+    uuid->timeLow = halUuid->timeLow;
+    uuid->timeMid = halUuid->timeMid;
+    uuid->versionAndTimeHigh = halUuid->timeHiAndVersion;
+    uuid->variantAndClockSeqHigh = halUuid->clockSeq;
+    memcpy(&uuid->node[0], &halUuid->node[0], 6);
+}
+
+void SoundTriggerHw::convertUuidToHal(sound_trigger_uuid_t* halUuid, const Uuid* uuid) {
+    halUuid->timeLow = uuid->timeLow;
+    halUuid->timeMid = uuid->timeMid;
+    halUuid->timeHiAndVersion = uuid->versionAndTimeHigh;
+    halUuid->clockSeq = uuid->variantAndClockSeqHigh;
+    memcpy(&halUuid->node[0], &uuid->node[0], 6);
+}
+
+void SoundTriggerHw::convertPropertiesFromHal(
+    ISoundTriggerHw::Properties* properties, const struct sound_trigger_properties* halProperties) {
+    properties->implementor = halProperties->implementor;
+    properties->description = halProperties->description;
+    properties->version = halProperties->version;
+    convertUuidFromHal(&properties->uuid, &halProperties->uuid);
+    properties->maxSoundModels = halProperties->max_sound_models;
+    properties->maxKeyPhrases = halProperties->max_key_phrases;
+    properties->maxUsers = halProperties->max_users;
+    properties->recognitionModes = halProperties->recognition_modes;
+    properties->captureTransition = halProperties->capture_transition;
+    properties->maxBufferMs = halProperties->max_buffer_ms;
+    properties->concurrentCapture = halProperties->concurrent_capture;
+    properties->triggerInEvent = halProperties->trigger_in_event;
+    properties->powerConsumptionMw = halProperties->power_consumption_mw;
+}
+
+void SoundTriggerHw::convertTriggerPhraseToHal(struct sound_trigger_phrase* halTriggerPhrase,
+                                               const ISoundTriggerHw::Phrase* triggerPhrase) {
+    halTriggerPhrase->id = triggerPhrase->id;
+    halTriggerPhrase->recognition_mode = triggerPhrase->recognitionModes;
+    unsigned int i;
+
+    halTriggerPhrase->num_users =
+        std::min((int)triggerPhrase->users.size(), SOUND_TRIGGER_MAX_USERS);
+    for (i = 0; i < halTriggerPhrase->num_users; i++) {
+        halTriggerPhrase->users[i] = triggerPhrase->users[i];
+    }
+
+    strlcpy(halTriggerPhrase->locale, triggerPhrase->locale.c_str(), SOUND_TRIGGER_MAX_LOCALE_LEN);
+    strlcpy(halTriggerPhrase->text, triggerPhrase->text.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
+}
+
+struct sound_trigger_sound_model* SoundTriggerHw::convertSoundModelToHal(
+    const V2_0::ISoundTriggerHw::SoundModel* soundModel) {
+    struct sound_trigger_sound_model* halModel = NULL;
+    if (soundModel->type == V2_0::SoundModelType::KEYPHRASE) {
+        size_t allocSize =
+            sizeof(struct sound_trigger_phrase_sound_model) + soundModel->data.size();
+        struct sound_trigger_phrase_sound_model* halKeyPhraseModel =
+            static_cast<struct sound_trigger_phrase_sound_model*>(malloc(allocSize));
+        LOG_ALWAYS_FATAL_IF(halKeyPhraseModel == NULL,
+                            "malloc failed for size %zu in convertSoundModelToHal PHRASE",
+                            allocSize);
+
+        const ISoundTriggerHw::PhraseSoundModel* keyPhraseModel =
+            reinterpret_cast<const ISoundTriggerHw::PhraseSoundModel*>(soundModel);
+
+        size_t i;
+        for (i = 0; i < keyPhraseModel->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
+            convertTriggerPhraseToHal(&halKeyPhraseModel->phrases[i], &keyPhraseModel->phrases[i]);
+        }
+        halKeyPhraseModel->num_phrases = (unsigned int)i;
+        halModel = reinterpret_cast<struct sound_trigger_sound_model*>(halKeyPhraseModel);
+        halModel->data_offset = sizeof(struct sound_trigger_phrase_sound_model);
+    } else {
+        size_t allocSize = sizeof(struct sound_trigger_sound_model) + soundModel->data.size();
+        halModel = static_cast<struct sound_trigger_sound_model*>(malloc(allocSize));
+        LOG_ALWAYS_FATAL_IF(halModel == NULL,
+                            "malloc failed for size %zu in convertSoundModelToHal GENERIC",
+                            allocSize);
+
+        halModel->data_offset = sizeof(struct sound_trigger_sound_model);
+    }
+    halModel->type = (sound_trigger_sound_model_type_t)soundModel->type;
+    convertUuidToHal(&halModel->uuid, &soundModel->uuid);
+    convertUuidToHal(&halModel->vendor_uuid, &soundModel->vendorUuid);
+    halModel->data_size = soundModel->data.size();
+    uint8_t* dst = reinterpret_cast<uint8_t*>(halModel) + halModel->data_offset;
+    const uint8_t* src = reinterpret_cast<const uint8_t*>(&soundModel->data[0]);
+    memcpy(dst, src, soundModel->data.size());
+
+    return halModel;
+}
+
+void SoundTriggerHw::convertPhraseRecognitionExtraToHal(
+    struct sound_trigger_phrase_recognition_extra* halExtra,
+    const V2_0::PhraseRecognitionExtra* extra) {
+    halExtra->id = extra->id;
+    halExtra->recognition_modes = extra->recognitionModes;
+    halExtra->confidence_level = extra->confidenceLevel;
+
+    unsigned int i;
+    for (i = 0; i < extra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
+        halExtra->levels[i].user_id = extra->levels[i].userId;
+        halExtra->levels[i].level = extra->levels[i].levelPercent;
+    }
+    halExtra->num_levels = i;
+}
+
+struct sound_trigger_recognition_config* SoundTriggerHw::convertRecognitionConfigToHal(
+    const V2_0::ISoundTriggerHw::RecognitionConfig* config) {
+    size_t allocSize = sizeof(struct sound_trigger_recognition_config) + config->data.size();
+    struct sound_trigger_recognition_config* halConfig =
+        static_cast<struct sound_trigger_recognition_config*>(malloc(allocSize));
+
+    LOG_ALWAYS_FATAL_IF(halConfig == NULL,
+                        "malloc failed for size %zu in convertRecognitionConfigToHal", allocSize);
+
+    halConfig->capture_handle = (audio_io_handle_t)config->captureHandle;
+    halConfig->capture_device = (audio_devices_t)config->captureDevice;
+    halConfig->capture_requested = config->captureRequested;
+
+    unsigned int i;
+    for (i = 0; i < config->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
+        convertPhraseRecognitionExtraToHal(&halConfig->phrases[i], &config->phrases[i]);
+    }
+    halConfig->num_phrases = i;
+
+    halConfig->data_offset = sizeof(struct sound_trigger_recognition_config);
+    halConfig->data_size = config->data.size();
+    uint8_t* dst = reinterpret_cast<uint8_t*>(halConfig) + halConfig->data_offset;
+    const uint8_t* src = reinterpret_cast<const uint8_t*>(&config->data[0]);
+    memcpy(dst, src, config->data.size());
+    return halConfig;
+}
+
+// static
+void SoundTriggerHw::convertSoundModelEventFromHal(
+    V2_0::ISoundTriggerHwCallback::ModelEvent* event,
+    const struct sound_trigger_model_event* halEvent) {
+    event->status = (V2_0::ISoundTriggerHwCallback::SoundModelStatus)halEvent->status;
+    // event->model to be remapped by called
+    event->data.setToExternal(
+        const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(halEvent)) + halEvent->data_offset,
+        halEvent->data_size);
+}
+
+// static
+void SoundTriggerHw::convertPhaseRecognitionEventFromHal(
+    V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent* event,
+    const struct sound_trigger_phrase_recognition_event* halEvent) {
+    event->phraseExtras.resize(halEvent->num_phrases);
+    for (unsigned int i = 0; i < halEvent->num_phrases; i++) {
+        convertPhraseRecognitionExtraFromHal(&event->phraseExtras[i], &halEvent->phrase_extras[i]);
+    }
+    convertRecognitionEventFromHal(&event->common, &halEvent->common);
+}
+
+// static
+void SoundTriggerHw::convertRecognitionEventFromHal(
+    V2_0::ISoundTriggerHwCallback::RecognitionEvent* event,
+    const struct sound_trigger_recognition_event* halEvent) {
+    event->status = static_cast<V2_0::ISoundTriggerHwCallback::RecognitionStatus>(halEvent->status);
+    event->type = static_cast<V2_0::SoundModelType>(halEvent->type);
+    // event->model to be remapped by called
+    event->captureAvailable = halEvent->capture_available;
+    event->captureSession = halEvent->capture_session;
+    event->captureDelayMs = halEvent->capture_delay_ms;
+    event->capturePreambleMs = halEvent->capture_preamble_ms;
+    event->triggerInData = halEvent->trigger_in_data;
+    event->audioConfig.sampleRateHz = halEvent->audio_config.sample_rate;
+    event->audioConfig.channelMask =
+        (audio::common::V2_0::AudioChannelMask)halEvent->audio_config.channel_mask;
+    event->audioConfig.format = (audio::common::V2_0::AudioFormat)halEvent->audio_config.format;
+    event->data.setToExternal(
+        const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(halEvent)) + halEvent->data_offset,
+        halEvent->data_size);
+}
+
+// static
+void SoundTriggerHw::convertPhraseRecognitionExtraFromHal(
+    V2_0::PhraseRecognitionExtra* extra,
+    const struct sound_trigger_phrase_recognition_extra* halExtra) {
+    extra->id = halExtra->id;
+    extra->recognitionModes = halExtra->recognition_modes;
+    extra->confidenceLevel = halExtra->confidence_level;
+
+    extra->levels.resize(halExtra->num_levels);
+    for (unsigned int i = 0; i < halExtra->num_levels; i++) {
+        extra->levels[i].userId = halExtra->levels[i].user_id;
+        extra->levels[i].levelPercent = halExtra->levels[i].level;
+    }
+}
+
+void SoundTriggerHw::SoundModelClient_2_0::recognitionCallback(
+    struct sound_trigger_recognition_event* halEvent) {
+    if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) {
+        V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent event;
+        convertPhaseRecognitionEventFromHal(
+            &event, reinterpret_cast<sound_trigger_phrase_recognition_event*>(halEvent));
+        event.common.model = mId;
+        mCallback->phraseRecognitionCallback(event, mCookie);
+    } else {
+        V2_0::ISoundTriggerHwCallback::RecognitionEvent event;
+        convertRecognitionEventFromHal(&event, halEvent);
+        event.model = mId;
+        mCallback->recognitionCallback(event, mCookie);
+    }
+}
+
+void SoundTriggerHw::SoundModelClient_2_0::soundModelCallback(
+    struct sound_trigger_model_event* halEvent) {
+    V2_0::ISoundTriggerHwCallback::ModelEvent event;
+    convertSoundModelEventFromHal(&event, halEvent);
+    event.model = mId;
+    mCallback->soundModelCallback(event, mCookie);
+}
+
+// Begin V2_1 implementation, copied from
+// hardware/interfaces/soundtrigger/2.1/default/SoundTriggerHw.cpp
+
+namespace {
+
+// Backs up by the vector with the contents of shared memory.
+// It is assumed that the passed hidl_vector is empty, so it's
+// not cleared if the memory is a null object.
+// The caller needs to keep the returned sp<IMemory> as long as
+// the data is needed.
+std::pair<bool, sp<IMemory>> memoryAsVector(const hidl_memory& m, hidl_vec<uint8_t>* vec) {
+    sp<IMemory> memory;
+    if (m.size() == 0) {
+        return std::make_pair(true, memory);
+    }
+    memory = mapMemory(m);
+    if (memory != nullptr) {
+        memory->read();
+        vec->setToExternal(static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())),
+                           memory->getSize());
+        return std::make_pair(true, memory);
+    }
+    ALOGE("%s: Could not map HIDL memory to IMemory", __func__);
+    return std::make_pair(false, memory);
+}
+
+// Moves the data from the vector into allocated shared memory,
+// emptying the vector.
+// It is assumed that the passed hidl_memory is a null object, so it's
+// not reset if the vector is empty.
+// The caller needs to keep the returned sp<IMemory> as long as
+// the data is needed.
+std::pair<bool, sp<IMemory>> moveVectorToMemory(hidl_vec<uint8_t>* v, hidl_memory* mem) {
+    sp<IMemory> memory;
+    if (v->size() == 0) {
+        return std::make_pair(true, memory);
+    }
+    sp<IAllocator> ashmem = IAllocator::getService("ashmem");
+    if (ashmem == 0) {
+        ALOGE("Failed to retrieve ashmem allocator service");
+        return std::make_pair(false, memory);
+    }
+    bool success = false;
+    Return<void> r = ashmem->allocate(v->size(), [&](bool s, const hidl_memory& m) {
+        success = s;
+        if (success) *mem = m;
+    });
+    if (r.isOk() && success) {
+        memory = hardware::mapMemory(*mem);
+        if (memory != 0) {
+            memory->update();
+            memcpy(memory->getPointer(), v->data(), v->size());
+            memory->commit();
+            v->resize(0);
+            return std::make_pair(true, memory);
+        } else {
+            ALOGE("Failed to map allocated ashmem");
+        }
+    } else {
+        ALOGE("Failed to allocate %llu bytes from ashmem", (unsigned long long)v->size());
+    }
+    return std::make_pair(false, memory);
+}
+
+}  // namespace
+
+Return<void> SoundTriggerHw::loadSoundModel_2_1(
+    const V2_1::ISoundTriggerHw::SoundModel& soundModel,
+    const sp<V2_1::ISoundTriggerHwCallback>& callback, int32_t cookie,
+    V2_1::ISoundTriggerHw::loadSoundModel_2_1_cb _hidl_cb) {
+    // It is assumed that legacy data vector is empty, thus making copy is cheap.
+    V2_0::ISoundTriggerHw::SoundModel soundModel_2_0(soundModel.header);
+    auto result = memoryAsVector(soundModel.data, &soundModel_2_0.data);
+    if (result.first) {
+        sp<SoundModelClient> client =
+            new SoundModelClient_2_1(nextUniqueModelId(), cookie, callback);
+        _hidl_cb(doLoadSoundModel(soundModel_2_0, client), client->getId());
+        return Void();
+    }
+    _hidl_cb(-ENOMEM, 0);
+    return Void();
+}
+
+Return<void> SoundTriggerHw::loadPhraseSoundModel_2_1(
+    const V2_1::ISoundTriggerHw::PhraseSoundModel& soundModel,
+    const sp<V2_1::ISoundTriggerHwCallback>& callback, int32_t cookie,
+    V2_1::ISoundTriggerHw::loadPhraseSoundModel_2_1_cb _hidl_cb) {
+    V2_0::ISoundTriggerHw::PhraseSoundModel soundModel_2_0;
+    // It is assumed that legacy data vector is empty, thus making copy is cheap.
+    soundModel_2_0.common = soundModel.common.header;
+    // Avoid copying phrases data.
+    soundModel_2_0.phrases.setToExternal(
+        const_cast<V2_0::ISoundTriggerHw::Phrase*>(soundModel.phrases.data()),
+        soundModel.phrases.size());
+    auto result = memoryAsVector(soundModel.common.data, &soundModel_2_0.common.data);
+    if (result.first) {
+        sp<SoundModelClient> client =
+            new SoundModelClient_2_1(nextUniqueModelId(), cookie, callback);
+        _hidl_cb(doLoadSoundModel((const V2_0::ISoundTriggerHw::SoundModel&)soundModel_2_0, client),
+                 client->getId());
+        return Void();
+    }
+    _hidl_cb(-ENOMEM, 0);
+    return Void();
+}
+
+Return<int32_t> SoundTriggerHw::startRecognition_2_1(
+    int32_t modelHandle, const V2_1::ISoundTriggerHw::RecognitionConfig& config,
+    const sp<V2_1::ISoundTriggerHwCallback>& callback, int32_t cookie) {
+    // It is assumed that legacy data vector is empty, thus making copy is cheap.
+    V2_0::ISoundTriggerHw::RecognitionConfig config_2_0(config.header);
+    auto result = memoryAsVector(config.data, &config_2_0.data);
+    return result.first ? startRecognition(modelHandle, config_2_0, callback, cookie)
+                        : Return<int32_t>(-ENOMEM);
+}
+
+void SoundTriggerHw::SoundModelClient_2_1::recognitionCallback(
+    struct sound_trigger_recognition_event* halEvent) {
+    if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) {
+        V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent event_2_0;
+        convertPhaseRecognitionEventFromHal(
+            &event_2_0, reinterpret_cast<sound_trigger_phrase_recognition_event*>(halEvent));
+        event_2_0.common.model = mId;
+        V2_1::ISoundTriggerHwCallback::PhraseRecognitionEvent event;
+        event.phraseExtras.setToExternal(event_2_0.phraseExtras.data(),
+                                         event_2_0.phraseExtras.size());
+        auto result = moveVectorToMemory(&event_2_0.common.data, &event.common.data);
+        if (result.first) {
+            // The data vector is now empty, thus copying is cheap.
+            event.common.header = event_2_0.common;
+            mCallback->phraseRecognitionCallback_2_1(event, mCookie);
+        }
+    } else {
+        V2_1::ISoundTriggerHwCallback::RecognitionEvent event;
+        convertRecognitionEventFromHal(&event.header, halEvent);
+        event.header.model = mId;
+        auto result = moveVectorToMemory(&event.header.data, &event.data);
+        if (result.first) {
+            mCallback->recognitionCallback_2_1(event, mCookie);
+        }
+    }
+}
+
+void SoundTriggerHw::SoundModelClient_2_1::soundModelCallback(
+    struct sound_trigger_model_event* halEvent) {
+    V2_1::ISoundTriggerHwCallback::ModelEvent event;
+    convertSoundModelEventFromHal(&event.header, halEvent);
+    event.header.model = mId;
+    auto result = moveVectorToMemory(&event.header.data, &event.data);
+    if (result.first) {
+        mCallback->soundModelCallback_2_1(event, mCookie);
+    }
+}
+
+// Begin V2_2 implementation
+
+Return<void> SoundTriggerHw::getModelState(int32_t modelHandle, getModelState_cb hidl_cb) {
+    int ret = 0;
+    V2_0::ISoundTriggerHwCallback::RecognitionEvent event;
+    struct sound_trigger_recognition_event* halEvent = NULL;
+    sp<SoundModelClient> client;
+    if (mHwDevice == NULL) {
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    {
+        AutoMutex lock(mLock);
+        client = mClients.valueFor(modelHandle);
+        if (client == 0) {
+            ret = -ENOSYS;
+            goto exit;
+        }
+    }
+
+    if (mHwDevice->get_model_state == NULL) {
+        ALOGE("Failed to get model state from device, no such method");
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    // Get the state from the device (as a recognition event)
+    halEvent = mHwDevice->get_model_state(mHwDevice, client->getHalHandle());
+    if (halEvent == NULL) {
+        ALOGE("Failed to get model state from device");
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    convertRecognitionEventFromHal(&event, halEvent);
+
+exit:
+    hidl_cb(ret, event);
+    free(halEvent);
+    return Void();
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+ISoundTriggerHw* HIDL_FETCH_ISoundTriggerHw(const char* /* name */) {
+    return new SoundTriggerHw();
+}
+
+}  // namespace implementation
+}  // namespace V2_2
+}  // namespace soundtrigger
+}  // namespace hardware
+}  // namespace android
diff --git a/soundtrigger/2.2/default/SoundTriggerHw.h b/soundtrigger/2.2/default/SoundTriggerHw.h
new file mode 100644
index 0000000..876b990
--- /dev/null
+++ b/soundtrigger/2.2/default/SoundTriggerHw.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_V2_2_SOUNDTRIGGERHW_H
+#define ANDROID_HARDWARE_SOUNDTRIGGER_V2_2_SOUNDTRIGGERHW_H
+
+#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
+#include <android/hardware/soundtrigger/2.0/ISoundTriggerHwCallback.h>
+#include <android/hardware/soundtrigger/2.2/ISoundTriggerHw.h>
+#include <hardware/sound_trigger.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <stdatomic.h>
+#include <system/sound_trigger.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+namespace android {
+namespace hardware {
+namespace soundtrigger {
+namespace V2_2 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::audio::common::V2_0::Uuid;
+using ::android::hardware::soundtrigger::V2_0::ISoundTriggerHwCallback;
+
+/**
+ * According to the HIDL C++ Users Guide: client and server implementations
+ * should never directly refer to anything other than the interface header
+ * generated from the HIDL definition file (ie. ISoundTriggerHw.hal), so
+ * this V2_2 implementation copies the V2_0 and V2_1 implementations and
+ * then adds the new V2_2 implementation.
+ */
+struct SoundTriggerHw : public ISoundTriggerHw {
+    // Methods from V2_0::ISoundTriggerHw follow.
+    Return<void> getProperties(getProperties_cb _hidl_cb) override;
+    Return<void> loadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
+                                const sp<V2_0::ISoundTriggerHwCallback>& callback, int32_t cookie,
+                                loadSoundModel_cb _hidl_cb) override;
+    Return<void> loadPhraseSoundModel(const V2_0::ISoundTriggerHw::PhraseSoundModel& soundModel,
+                                      const sp<V2_0::ISoundTriggerHwCallback>& callback,
+                                      int32_t cookie, loadPhraseSoundModel_cb _hidl_cb) override;
+    Return<int32_t> unloadSoundModel(int32_t modelHandle) override;
+    Return<int32_t> startRecognition(int32_t modelHandle,
+                                     const V2_0::ISoundTriggerHw::RecognitionConfig& config,
+                                     const sp<V2_0::ISoundTriggerHwCallback>& callback,
+                                     int32_t cookie) override;
+    Return<int32_t> stopRecognition(int32_t modelHandle) override;
+    Return<int32_t> stopAllRecognitions() override;
+
+    // Methods from V2_1::ISoundTriggerHw follow.
+    Return<void> loadSoundModel_2_1(const V2_1::ISoundTriggerHw::SoundModel& soundModel,
+                                    const sp<V2_1::ISoundTriggerHwCallback>& callback,
+                                    int32_t cookie, loadSoundModel_2_1_cb _hidl_cb) override;
+    Return<void> loadPhraseSoundModel_2_1(const V2_1::ISoundTriggerHw::PhraseSoundModel& soundModel,
+                                          const sp<V2_1::ISoundTriggerHwCallback>& callback,
+                                          int32_t cookie,
+                                          loadPhraseSoundModel_2_1_cb _hidl_cb) override;
+    Return<int32_t> startRecognition_2_1(int32_t modelHandle,
+                                         const V2_1::ISoundTriggerHw::RecognitionConfig& config,
+                                         const sp<V2_1::ISoundTriggerHwCallback>& callback,
+                                         int32_t cookie) override;
+
+    // Methods from V2_2::ISoundTriggerHw follow.
+    Return<void> getModelState(int32_t modelHandle, getModelState_cb _hidl_cb) override;
+
+    SoundTriggerHw();
+
+    // Copied from hardware/interfaces/soundtrigger/2.0/default/SoundTriggerHalImpl.h
+    class SoundModelClient : public RefBase {
+       public:
+        SoundModelClient(uint32_t id, V2_0::ISoundTriggerHwCallback::CallbackCookie cookie)
+            : mId(id), mCookie(cookie) {}
+        virtual ~SoundModelClient() {}
+
+        uint32_t getId() const { return mId; }
+        sound_model_handle_t getHalHandle() const { return mHalHandle; }
+        void setHalHandle(sound_model_handle_t handle) { mHalHandle = handle; }
+
+        virtual void recognitionCallback(struct sound_trigger_recognition_event* halEvent) = 0;
+        virtual void soundModelCallback(struct sound_trigger_model_event* halEvent) = 0;
+
+       protected:
+        const uint32_t mId;
+        sound_model_handle_t mHalHandle;
+        V2_0::ISoundTriggerHwCallback::CallbackCookie mCookie;
+    };
+
+   protected:
+    static void convertPhaseRecognitionEventFromHal(
+        V2_0::ISoundTriggerHwCallback::PhraseRecognitionEvent* event,
+        const struct sound_trigger_phrase_recognition_event* halEvent);
+    static void convertRecognitionEventFromHal(
+        V2_0::ISoundTriggerHwCallback::RecognitionEvent* event,
+        const struct sound_trigger_recognition_event* halEvent);
+    static void convertSoundModelEventFromHal(V2_0::ISoundTriggerHwCallback::ModelEvent* event,
+                                              const struct sound_trigger_model_event* halEvent);
+
+    virtual ~SoundTriggerHw();
+
+    uint32_t nextUniqueModelId();
+    int doLoadSoundModel(const V2_0::ISoundTriggerHw::SoundModel& soundModel,
+                         sp<SoundModelClient> client);
+
+    // RefBase
+    void onFirstRef() override;
+
+   private:
+    class SoundModelClient_2_0 : public SoundModelClient {
+       public:
+        SoundModelClient_2_0(uint32_t id, V2_0::ISoundTriggerHwCallback::CallbackCookie cookie,
+                             sp<V2_0::ISoundTriggerHwCallback> callback)
+            : SoundModelClient(id, cookie), mCallback(callback) {}
+
+        void recognitionCallback(struct sound_trigger_recognition_event* halEvent) override;
+        void soundModelCallback(struct sound_trigger_model_event* halEvent) override;
+
+       private:
+        sp<V2_0::ISoundTriggerHwCallback> mCallback;
+    };
+
+    void convertUuidFromHal(Uuid* uuid, const sound_trigger_uuid_t* halUuid);
+    void convertUuidToHal(sound_trigger_uuid_t* halUuid, const Uuid* uuid);
+    void convertPropertiesFromHal(V2_0::ISoundTriggerHw::Properties* properties,
+                                  const struct sound_trigger_properties* halProperties);
+    void convertTriggerPhraseToHal(struct sound_trigger_phrase* halTriggerPhrase,
+                                   const V2_0::ISoundTriggerHw::Phrase* triggerPhrase);
+    // returned HAL sound model must be freed by caller
+    struct sound_trigger_sound_model* convertSoundModelToHal(
+        const V2_0::ISoundTriggerHw::SoundModel* soundModel);
+    void convertPhraseRecognitionExtraToHal(struct sound_trigger_phrase_recognition_extra* halExtra,
+                                            const V2_0::PhraseRecognitionExtra* extra);
+    // returned recognition config must be freed by caller
+    struct sound_trigger_recognition_config* convertRecognitionConfigToHal(
+        const V2_0::ISoundTriggerHw::RecognitionConfig* config);
+
+    static void convertPhraseRecognitionExtraFromHal(
+        V2_0::PhraseRecognitionExtra* extra,
+        const struct sound_trigger_phrase_recognition_extra* halExtra);
+
+    static void soundModelCallback(struct sound_trigger_model_event* halEvent, void* cookie);
+    static void recognitionCallback(struct sound_trigger_recognition_event* halEvent, void* cookie);
+
+    const char* mModuleName;
+    struct sound_trigger_hw_device* mHwDevice;
+    volatile atomic_uint_fast32_t mNextModelId;
+    DefaultKeyedVector<int32_t, sp<SoundModelClient> > mClients;
+    Mutex mLock;
+
+    // Copied from hardware/interfaces/soundtrigger/2.1/default/SoundTriggerHw.h
+    class SoundModelClient_2_1 : public SoundModelClient {
+       public:
+        SoundModelClient_2_1(uint32_t id, V2_1::ISoundTriggerHwCallback::CallbackCookie cookie,
+                             sp<V2_1::ISoundTriggerHwCallback> callback)
+            : SoundModelClient(id, cookie), mCallback(callback) {}
+
+        void recognitionCallback(struct sound_trigger_recognition_event* halEvent) override;
+        void soundModelCallback(struct sound_trigger_model_event* halEvent) override;
+
+       private:
+        sp<V2_1::ISoundTriggerHwCallback> mCallback;
+    };
+};
+
+extern "C" ISoundTriggerHw* HIDL_FETCH_ISoundTriggerHw(const char* name);
+
+}  // namespace implementation
+}  // namespace V2_2
+}  // namespace soundtrigger
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_SOUNDTRIGGER_V2_2_SOUNDTRIGGERHW_H
diff --git a/soundtrigger/2.2/vts/functional/VtsHalSoundtriggerV2_2TargetTest.cpp b/soundtrigger/2.2/vts/functional/VtsHalSoundtriggerV2_2TargetTest.cpp
new file mode 100644
index 0000000..a473c37
--- /dev/null
+++ b/soundtrigger/2.2/vts/functional/VtsHalSoundtriggerV2_2TargetTest.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SoundTriggerHidlHalTest"
+#include <stdlib.h>
+#include <time.h>
+
+#include <condition_variable>
+#include <mutex>
+
+#include <android/log.h>
+#include <cutils/native_handle.h>
+#include <log/log.h>
+
+#include <android/hardware/audio/common/2.0/types.h>
+#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
+#include <android/hardware/soundtrigger/2.2/ISoundTriggerHw.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::soundtrigger::V2_0::ISoundTriggerHwCallback;
+using ::android::hardware::soundtrigger::V2_0::SoundModelHandle;
+using ::android::hardware::soundtrigger::V2_2::ISoundTriggerHw;
+
+// Test environment for SoundTrigger HIDL HAL.
+class SoundTriggerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static SoundTriggerHidlEnvironment* Instance() {
+        static SoundTriggerHidlEnvironment* instance = new SoundTriggerHidlEnvironment;
+        return instance;
+    }
+
+    void registerTestServices() override { registerTestService<ISoundTriggerHw>(); }
+
+   private:
+    SoundTriggerHidlEnvironment() {}
+};
+
+// The main test class for Sound Trigger HIDL HAL.
+class SoundTriggerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    void SetUp() override {
+        mSoundTriggerHal = ::testing::VtsHalHidlTargetTestBase::getService<ISoundTriggerHw>(
+            SoundTriggerHidlEnvironment::Instance()->getServiceName<ISoundTriggerHw>());
+        ASSERT_NE(nullptr, mSoundTriggerHal.get());
+    }
+
+    static void SetUpTestCase() { srand(1234); }
+
+    void TearDown() override {}
+
+   protected:
+    sp<ISoundTriggerHw> mSoundTriggerHal;
+};
+
+/**
+ * Test ISoundTriggerHw::getModelState() method
+ *
+ * Verifies that:
+ *  - the implementation returns -EINVAL with invalid model handle
+ *
+ */
+TEST_F(SoundTriggerHidlTest, GetModelStateInvalidModel) {
+    int ret = android::OK;
+    ::android::hardware::soundtrigger::V2_0::ISoundTriggerHwCallback::RecognitionEvent event;
+    SoundModelHandle handle = 0;
+    Return<void> hidlReturn =
+        mSoundTriggerHal->getModelState(handle, [&](int32_t retval, auto res) {
+            ret = retval;
+            event = res;
+        });
+
+    EXPECT_TRUE(hidlReturn.isOk());
+    EXPECT_EQ(-ENOSYS, ret);
+}
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(SoundTriggerHidlEnvironment::Instance());
+    ::testing::InitGoogleTest(&argc, argv);
+    SoundTriggerHidlEnvironment::Instance()->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGI("Test result = %d", status);
+    return status;
+}
diff --git a/tests/expression/1.0/IExpression.hal b/tests/expression/1.0/IExpression.hal
index 2db9f61..36aed60 100644
--- a/tests/expression/1.0/IExpression.hal
+++ b/tests/expression/1.0/IExpression.hal
@@ -147,6 +147,28 @@
     logand4 = (0 && 1) == 0,
   };
 
+  // Tests for enum tags
+  enum NoElements : uint32_t {};
+  enum OneElement : uint32_t {A};
+  enum TwoElement : uint32_t {A,B};
+  enum TwoCollidingElements : uint32_t {A=1,B=1};
+  enum ThreeFromInheritance : TwoElement {C};
+  enum ThreeFromDoubleInheritance : ThreeFromInheritance {};
+  enum ThreeCollidingFromInheritance : TwoCollidingElements {C};
+
+  enum EnumTagTest : uint32_t {
+    a = NoElements#len == 0,
+    b = OneElement#len == 1,
+    c = TwoElement#len == 2,
+    d = TwoCollidingElements#len == 2,
+    e = ThreeFromInheritance#len == 3,
+    f = ThreeFromDoubleInheritance#len == 3,
+    g = ThreeCollidingFromInheritance#len == 3,
+
+    // fine to reference current enum as well
+    h = EnumTagTest#len == 8,
+  };
+
   enum Grayscale : int8_t {
     WHITE = 126,
     GRAY, // 127
diff --git a/thermal/2.0/IThermal.hal b/thermal/2.0/IThermal.hal
index 548ac9d..f890694 100644
--- a/thermal/2.0/IThermal.hal
+++ b/thermal/2.0/IThermal.hal
@@ -42,7 +42,7 @@
         generates (ThermalStatus status, vec<Temperature> temperatures);
 
     /**
-     * Retrieves temperature thresholds in Celsius.
+     * Retrieves static temperature thresholds in Celsius.
      *
      * @param filterType whether to filter the result for a given type.
      * @param type the TemperatureType such as battery or skin.
@@ -54,7 +54,11 @@
      *    devices (such as CPUs, GPUs and etc.) in the list must be kept
      *    the same regardless of the number of calls to this method even if
      *    they go offline, if these devices exist on boot. The method
-     *    always returns and never removes such temperatures.
+     *    always returns and never removes such temperatures. The thresholds
+     *    are returned as static values and must not change across calls. The actual
+     *    throttling state is determined in driver and HAL and must not be simply
+     *    compared with these thresholds. To get accurate throttling status, use
+     *    getCurrentTemperatures or registerThermalChangedCallback and listen.
      */
     getTemperatureThresholds(bool filterType, TemperatureType type)
         generates (ThermalStatus status, vec<TemperatureThreshold> temperatureThresholds);
diff --git a/thermal/2.0/default/android.hardware.thermal@2.0-service.xml b/thermal/2.0/default/android.hardware.thermal@2.0-service.xml
index c4c7d4d..bcd6344 100644
--- a/thermal/2.0/default/android.hardware.thermal@2.0-service.xml
+++ b/thermal/2.0/default/android.hardware.thermal@2.0-service.xml
@@ -2,6 +2,7 @@
     <hal format="hidl">
         <name>android.hardware.thermal</name>
         <transport>hwbinder</transport>
+        <version>1.0</version>
         <version>2.0</version>
         <interface>
             <name>IThermal</name>
diff --git a/thermal/2.0/types.hal b/thermal/2.0/types.hal
index 7b60d00..4929e44 100644
--- a/thermal/2.0/types.hal
+++ b/thermal/2.0/types.hal
@@ -22,6 +22,12 @@
 enum TemperatureType : @1.0::TemperatureType {
     USB_PORT = 4,
     POWER_AMPLIFIER = 5,
+    /**
+     * Battery Charge Limit - virtual thermal sensors
+     */
+    BCL_VOLTAGE = 6,
+    BCL_CURRENT = 7,
+    BCL_PERCENTAGE = 8,
 };
 
 
@@ -88,6 +94,7 @@
      * Hot throttling temperature constant for this temperature sensor in
      * level defined in ThrottlingSeverity including shutdown. Throttling
      * happens when temperature >= threshold. If not available, set to NAN.
+     * Unit is same as Temperature's value.
      */
     float[ThrottlingSeverityCount:NUM_THROTTLING_LEVELS] hotThrottlingThresholds;
 
@@ -95,13 +102,14 @@
      * Cold throttling temperature constant for this temperature sensor in
      * level defined in ThrottlingSeverity including shutdown. Throttling
      * happens when temperature <= threshold. If not available, set to NAN.
+     * Unit is same as Temperature's value.
      */
     float[ThrottlingSeverityCount:NUM_THROTTLING_LEVELS] coldThrottlingThresholds;
 
     /**
      * Threshold temperature above which the VR mode clockrate minimums cannot
-     * be maintained for this device.
-     * If not available, set by HAL to NAN.
+     * be maintained for this device. If not available, set by HAL to NAN.
+     * Unit is same as Temperature's value.
      */
     float vrThrottlingThreshold;
 };
@@ -121,7 +129,10 @@
     string name;
 
     /**
-     * Current temperature in Celsius. If not available set by HAL to NAN.
+     * For BCL, this is the current reading of the virtual sensor and the unit is
+     * millivolt, milliamp, percentage for BCL_VOLTAGE, BCL_CURRENT and BCL_PERCENTAGE
+     * respectively. For everything else, this is the current temperature in Celsius.
+     * If not available set by HAL to NAN.
      */
     float value;
 
diff --git a/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp b/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp
index 535f618..cf1956d 100644
--- a/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp
+++ b/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp
@@ -23,6 +23,7 @@
 #include <VtsHalHidlTargetTestEnvBase.h>
 
 using ::android::sp;
+using ::android::hardware::hidl_enum_range;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
@@ -183,9 +184,8 @@
                                              EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
                                          }
                                      });
-    for (int i = static_cast<int>(TemperatureType::UNKNOWN);
-         i <= static_cast<int>(TemperatureType::POWER_AMPLIFIER); ++i) {
-        auto type = static_cast<TemperatureType>(i);
+    auto types = hidl_enum_range<TemperatureType>();
+    for (const auto& type : types) {
         mThermal->getCurrentTemperatures(
             true, type, [&type](ThermalStatus status, hidl_vec<Temperature> temperatures) {
                 if (temperatures.size()) {
diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
index d16f1e7..a3fdf27 100644
--- a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
@@ -735,10 +735,10 @@
  * CreateRttController
  */
 TEST_F(WifiChipHidlTest, CreateRttController) {
-    configureChipForIfaceType(IfaceType::AP, true);
+    configureChipForIfaceType(IfaceType::STA, true);
 
-    sp<IWifiApIface> iface;
-    EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&iface));
+    sp<IWifiStaIface> iface;
+    EXPECT_EQ(WifiStatusCode::SUCCESS, createStaIface(&iface));
     EXPECT_NE(nullptr, iface.get());
 
     const auto& status_and_rtt_controller =
diff --git a/wifi/supplicant/1.2/Android.bp b/wifi/supplicant/1.2/Android.bp
new file mode 100644
index 0000000..bafd148
--- /dev/null
+++ b/wifi/supplicant/1.2/Android.bp
@@ -0,0 +1,19 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.wifi.supplicant@1.2",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "ISupplicantStaNetwork.hal",
+    ],
+    interfaces: [
+        "android.hardware.wifi.supplicant@1.0",
+        "android.hardware.wifi.supplicant@1.1",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+}
+
diff --git a/wifi/supplicant/1.2/ISupplicantStaNetwork.hal b/wifi/supplicant/1.2/ISupplicantStaNetwork.hal
new file mode 100644
index 0000000..85b233d
--- /dev/null
+++ b/wifi/supplicant/1.2/ISupplicantStaNetwork.hal
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2018 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.supplicant@1.2;
+
+import @1.0::ISupplicantStaNetworkCallback;
+import @1.0::ISupplicantStaNetwork;
+import @1.0::SupplicantStatus;
+import @1.1::ISupplicantStaNetwork;
+
+/**
+ * Interface exposed by the supplicant for each station mode network
+ * configuration it controls.
+ */
+interface ISupplicantStaNetwork extends @1.1::ISupplicantStaNetwork {
+    /** Possble mask of values for KeyMgmt param. */
+    enum KeyMgmtMask : @1.0::ISupplicantStaNetwork.KeyMgmtMask {
+        /** WPA3-Personal SAE Key management */
+        SAE = 1 << 10,
+
+        /** WPA3-Enterprise Suite-B Key management */
+        SUITE_B_192 = 1 << 17,
+
+        /** Enhacned Open (OWE) Key management */
+        OWE = 1 << 22,
+    };
+
+    /** Possble mask of values for PairwiseCipher param. */
+    enum PairwiseCipherMask : @1.0::ISupplicantStaNetwork.PairwiseCipherMask {
+        /** GCMP-256 Pairwise Cipher */
+        GCMP_256 = 1 << 8,
+    };
+
+    /** Possble mask of values for GroupCipher param. */
+    enum GroupCipherMask : @1.0::ISupplicantStaNetwork.GroupCipherMask {
+        /** GCMP-256 Group Cipher */
+        GCMP_256 = 1 << 8,
+    };
+
+    /** Possble mask of values for GroupMgmtCipher param. */
+    enum GroupMgmtCipherMask : uint32_t {
+        /** BIP_GMAC-128 Group Management Cipher */
+        BIP_GMAC_128 = 1 << 11,
+
+        /** BIP_GMAC-256 Group Management Cipher */
+        BIP_GMAC_256 = 1 << 12,
+
+        /** BIP_CMAC-256 Group Management Cipher */
+        BIP_CMAC_256 = 1 << 13,
+    };
+
+    /**
+     * Set key management mask for the network.
+     *
+     * @param keyMgmtMask value to set.
+     *        Combination of |KeyMgmtMask| values.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    setKeyMgmt_1_2(bitfield<KeyMgmtMask> keyMgmtMask) generates (SupplicantStatus status);
+
+    /**
+     * Get the key mgmt mask set for the network.
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     * @return keyMgmtMask Combination of |KeyMgmtMask| values.
+     */
+    getKeyMgmt_1_2()
+        generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask);
+
+    /**
+     * Set pairwise cipher mask for the network.
+     *
+     * @param pairwiseCipherMask value to set.
+     *        Combination of |PairwiseCipherMask| values.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    setPairwiseCipher_1_2(bitfield<PairwiseCipherMask> pairwiseCipherMask)
+        generates (SupplicantStatus status);
+
+    /**
+     * Get the pairwise cipher mask set for the network.
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     * @return pairwiseCipherMask Combination of |PairwiseCipherMask| values.
+     */
+    getPairwiseCipher_1_2()
+        generates (SupplicantStatus status,
+            bitfield<PairwiseCipherMask> pairwiseCipherMask);
+
+    /**
+     * Set group cipher mask for the network.
+     *
+     * @param groupCipherMask value to set.
+     *        Combination of |GroupCipherMask| values.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    setGroupCipher_1_2(bitfield<GroupCipherMask> groupCipherMask)
+        generates (SupplicantStatus status);
+
+    /**
+     * Get the group cipher mask set for the network.
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     * @return groupCipherMask Combination of |GroupCipherMask| values.
+     */
+    getGroupCipher_1_2()
+        generates (SupplicantStatus status,
+            bitfield<GroupCipherMask> groupCipherMask);
+
+    /**
+     * Set group management cipher mask for the network.
+     *
+     * @param groupMgmtCipherMask value to set.
+     *        Combination of |GroupMgmtCipherMask| values.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    setGroupMgmtCipher(bitfield<GroupMgmtCipherMask> groupMgmtCipherMask)
+        generates (SupplicantStatus status);
+
+    /**
+     * Get the group management cipher mask set for the network.
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     * @return groupMgmtCipherMask Combination of |GroupMgmtCipherMask| values.
+     */
+    getGroupMgmtCipher()
+        generates (SupplicantStatus status,
+            bitfield<GroupMgmtCipherMask> groupMgmtCipherMask);
+
+    /**
+     * Enable TLS Suite-B in EAP Phase1
+     *
+     * @param enable Set to true to enable TLS Suite-B in EAP phase1
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    enableTlsSuiteBEapPhase1Param(bool enable)
+        generates (SupplicantStatus status);
+
+    /**
+     * Set EAP OpenSSL Suite-B-192 ciphers for WPA3-Enterprise
+     *        Supported option:
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    enableSuiteBEapOpenSslCiphers()
+        generates (SupplicantStatus status);
+
+    /**
+     * Get SAE password for WPA3-Personal
+     *
+     * @return status Status of the operation, and a string.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    getSaePassword()
+        generates (SupplicantStatus status, string saePassword);
+
+    /**
+     * Get SAE password ID for WPA3-Personal
+     *
+     * @return status Status of the operation, and a string.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    getSaePasswordId()
+        generates (SupplicantStatus status, string saePasswordId);
+
+    /**
+    * Set SAE password for WPA3-Personal
+    *
+    * @param saePassword string with the above option
+    *
+    * @return status Status of the operation.
+    *         Possible status codes:
+    *         |SupplicantStatusCode.SUCCESS|,
+    *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+    *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+    *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+    */
+    setSaePassword(string saePassword)
+        generates (SupplicantStatus status);
+
+    /**
+     * Set SAE password ID for WPA3-Personal
+     *
+     * @param sae_password_id string with the above option
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    setSaePasswordId(string saePasswordId)
+        generates (SupplicantStatus status);
+
+    /**
+     * Get Key management capabilities of the device
+     *
+     * @return status Status of the operation, and a string.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    getKeyMgmtCapabilities()
+        generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask);
+};