Merge "Register default accelerometer sensor"
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index 4f77348..ba81a52 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -156,6 +156,29 @@
                 // Placeholder for future implementation of VMS property in the default hal. For
                 // now, just returns OK; otherwise, hal clients crash with property not supported.
                 return StatusCode::OK;
+            case AP_POWER_STATE_REPORT:
+                switch (propValue.value.int32Values[0]) {
+                    case toInt(VehicleApPowerStateReport::DEEP_SLEEP_EXIT):
+                    case toInt(VehicleApPowerStateReport::SHUTDOWN_CANCELLED):
+                    case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL):
+                        // CPMS is in WAIT_FOR_VHAL state, simply move to ON
+                        doHalEvent(createApPowerStateReq(VehicleApPowerStateReq::ON, 0));
+                        break;
+                    case toInt(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY):
+                    case toInt(VehicleApPowerStateReport::SHUTDOWN_START):
+                        // CPMS is in WAIT_FOR_FINISH state, send the FINISHED command
+                        doHalEvent(createApPowerStateReq(VehicleApPowerStateReq::FINISHED, 0));
+                        break;
+                    case toInt(VehicleApPowerStateReport::ON):
+                    case toInt(VehicleApPowerStateReport::SHUTDOWN_POSTPONE):
+                    case toInt(VehicleApPowerStateReport::SHUTDOWN_PREPARE):
+                        // Do nothing
+                        break;
+                    default:
+                        // Unknown state
+                        break;
+                }
+                break;
         }
     }
 
@@ -401,6 +424,18 @@
     return StatusCode::OK;
 }
 
+VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createApPowerStateReq(
+    VehicleApPowerStateReq state, int32_t param) {
+    auto req = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 2);
+    req->prop = toInt(VehicleProperty::AP_POWER_STATE_REQ);
+    req->areaId = 0;
+    req->timestamp = elapsedRealtimeNano();
+    req->status = VehiclePropertyStatus::AVAILABLE;
+    req->value.int32Values[0] = toInt(state);
+    req->value.int32Values[1] = param;
+    return req;
+}
+
 VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createHwInputKeyProp(
     VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay) {
     auto keyEvent = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 3);
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index ec59690..78895e3 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -67,6 +67,7 @@
 
     StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
     void onFakeValueGenerated(const VehiclePropValue& value);
+    VehiclePropValuePtr createApPowerStateReq(VehicleApPowerStateReq req, int32_t param);
     VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
                                              int32_t targetDisplay);
 
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..ae84ec2 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -28,13 +28,13 @@
 #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_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
@@ -191,12 +191,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();
@@ -659,10 +659,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 +671,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 +697,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 +710,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/boot/1.0/default/Android.mk b/boot/1.0/default/Android.mk
new file mode 100644
index 0000000..7ccc4c8
--- /dev/null
+++ b/boot/1.0/default/Android.mk
@@ -0,0 +1,30 @@
+# TODO(connoro): Remove this file once we eliminate existing usage of
+# PRODUCT_STATIC_BOOT_CONTROL_HAL
+
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(strip $(PRODUCT_STATIC_BOOT_CONTROL_HAL)),)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := android.hardware.boot@1.0-impl-wrapper.recovery
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MULTILIB := first
+ifeq ($(TARGET_IS_64_BIT),true)
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib64/hw
+else
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib/hw
+endif
+LOCAL_SRC_FILES := BootControl.cpp
+LOCAL_CFLAGS := -DBOOT_CONTROL_RECOVERY
+LOCAL_SHARED_LIBRARIES := \
+    libbase.recovery \
+    liblog.recovery \
+    libhidlbase.recovery \
+    libhidltransport.recovery \
+    libhardware.recovery \
+    libutils.recovery \
+    android.hardware.boot@1.0.recovery
+LOCAL_STATIC_LIBRARIES := $(PRODUCT_STATIC_BOOT_CONTROL_HAL)
+include $(BUILD_SHARED_LIBRARY)
+
+endif
diff --git a/boot/1.0/default/BootControl.cpp b/boot/1.0/default/BootControl.cpp
index 9a90076..e36407f 100644
--- a/boot/1.0/default/BootControl.cpp
+++ b/boot/1.0/default/BootControl.cpp
@@ -21,6 +21,10 @@
 #include <hardware/boot_control.h>
 #include "BootControl.h"
 
+#ifdef BOOT_CONTROL_RECOVERY
+extern const hw_module_t HAL_MODULE_INFO_SYM;
+#endif
+
 namespace android {
 namespace hardware {
 namespace boot {
@@ -92,7 +96,23 @@
     return Void();
 }
 
+#ifdef BOOT_CONTROL_RECOVERY
+IBootControl* HIDL_FETCH_IBootControl(const char * /* hal */) {
+    boot_control_module_t* module;
 
+    // For devices that don't build a standalone libhardware bootctrl impl for recovery,
+    // we simulate the hw_get_module() by accessing it from the current process directly.
+    const hw_module_t* hw_module = &HAL_MODULE_INFO_SYM;
+    if (!hw_module ||
+        strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
+        ALOGE("Error loading boot_control HAL implementation: %d.", -EINVAL);
+        return nullptr;
+    }
+    module = reinterpret_cast<boot_control_module_t*>(const_cast<hw_module_t*>(hw_module));
+    module->init(module);
+    return new BootControl(module);
+}
+#else
 IBootControl* HIDL_FETCH_IBootControl(const char* /* hal */) {
     int ret = 0;
     boot_control_module_t* module = NULL;
@@ -106,7 +126,7 @@
     module->init(module);
     return new BootControl(module);
 }
-
+#endif
 } // namespace implementation
 }  // namespace V1_0
 }  // namespace boot
diff --git a/broadcastradio/common/utils2x/Android.bp b/broadcastradio/common/utils2x/Android.bp
index aab94f2..df2cefe 100644
--- a/broadcastradio/common/utils2x/Android.bp
+++ b/broadcastradio/common/utils2x/Android.bp
@@ -22,6 +22,7 @@
         "-Wall",
         "-Wextra",
         "-Werror",
+        "-Wno-error=implicit-fallthrough",
     ],
     cppflags: [
         "-std=c++1z",
diff --git a/broadcastradio/common/utils2x/Utils.cpp b/broadcastradio/common/utils2x/Utils.cpp
index 3e20b35..f292c08 100644
--- a/broadcastradio/common/utils2x/Utils.cpp
+++ b/broadcastradio/common/utils2x/Utils.cpp
@@ -215,7 +215,7 @@
             break;
         case IdentifierType::DAB_FREQUENCY:
             expect(val > 100000u, "f > 100MHz");
-        // fallthrough
+            [[fallthrough]];
         case IdentifierType::AMFM_FREQUENCY:
         case IdentifierType::DRMO_FREQUENCY:
             expect(val > 100u, "f > 100kHz");
diff --git a/configstore/1.2/Android.bp b/configstore/1.2/Android.bp
index cc5644c..c525a72 100644
--- a/configstore/1.2/Android.bp
+++ b/configstore/1.2/Android.bp
@@ -12,8 +12,8 @@
     interfaces: [
         "android.hardware.configstore@1.1",
         "android.hardware.configstore@1.0",
-        "android.hardware.graphics.common@1.1",
+        "android.hardware.graphics.common@1.2",
         "android.hidl.base@1.0",
     ],
     gen_java: true,
-}
\ No newline at end of file
+}
diff --git a/configstore/1.2/ISurfaceFlingerConfigs.hal b/configstore/1.2/ISurfaceFlingerConfigs.hal
index c879155..9553fca 100644
--- a/configstore/1.2/ISurfaceFlingerConfigs.hal
+++ b/configstore/1.2/ISurfaceFlingerConfigs.hal
@@ -15,8 +15,8 @@
  */
 package android.hardware.configstore@1.2;
 
-import android.hardware.graphics.common@1.1::Dataspace;
 import android.hardware.graphics.common@1.1::PixelFormat;
+import android.hardware.graphics.common@1.2::Dataspace;
 import @1.1::ISurfaceFlingerConfigs;
 import @1.0::OptionalBool;
 
diff --git a/configstore/1.2/default/SurfaceFlingerConfigs.cpp b/configstore/1.2/default/SurfaceFlingerConfigs.cpp
index ae19dc0..b78d15e 100644
--- a/configstore/1.2/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.2/default/SurfaceFlingerConfigs.cpp
@@ -26,8 +26,8 @@
 namespace V1_2 {
 namespace implementation {
 
-using ::android::hardware::graphics::common::V1_1::Dataspace;
 using ::android::hardware::graphics::common::V1_1::PixelFormat;
+using ::android::hardware::graphics::common::V1_2::Dataspace;
 
 // ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs implementation.
 Return<void> SurfaceFlingerConfigs::vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) {
diff --git a/current.txt b/current.txt
index a7989d4..ef83acc 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
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
new file mode 100644
index 0000000..a3ebdbf
--- /dev/null
+++ b/graphics/common/1.2/Android.bp
@@ -0,0 +1,25 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.graphics.common@1.2",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
+    srcs: [
+        "types.hal",
+    ],
+    interfaces: [
+        "android.hardware.graphics.common@1.0",
+        "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
new file mode 100644
index 0000000..15f2c14
--- /dev/null
+++ b/graphics/common/1.2/types.hal
@@ -0,0 +1,89 @@
+/*
+ * 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.common@1.2;
+
+import @1.1::BufferUsage;
+import @1.1::ColorMode;
+import @1.1::Dataspace;
+import @1.1::PixelFormat;
+
+@export(name="android_dataspace_v1_2_t", value_prefix="HAL_DATASPACE_",
+        export_parent="false")
+enum Dataspace : @1.1::Dataspace {
+    /**
+     * ITU-R Recommendation 2020 (BT.2020)
+     *
+     * Ultra High-definition television
+     *
+     * Use full range, sRGB transfer and BT2020 standard
+     */
+    DISPLAY_BT2020 = STANDARD_BT2020 | TRANSFER_SRGB | RANGE_FULL,
+};
+
+enum ColorMode : @1.1::ColorMode {
+    /**
+     * DISPLAY_BT2020 corresponds with display settings that implement the ITU-R
+     * Recommendation BT.2020 / Rec. 2020 for UHDTV, but specifies an SRGB
+     * transfer function.
+     *
+     * Primaries:
+     *                  x       y
+     *  green           0.170   0.797
+     *  blue            0.131   0.046
+     *  red             0.708   0.292
+     *  white (D65)     0.3127  0.3290
+     *
+     * Transfer Function is sRGB
+     */
+    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.3/Android.bp b/graphics/composer/2.3/Android.bp
index 78da099..6d29348 100644
--- a/graphics/composer/2.3/Android.bp
+++ b/graphics/composer/2.3/Android.bp
@@ -13,6 +13,7 @@
     interfaces: [
         "android.hardware.graphics.common@1.0",
         "android.hardware.graphics.common@1.1",
+        "android.hardware.graphics.common@1.2",
         "android.hardware.graphics.composer@2.1",
         "android.hardware.graphics.composer@2.2",
         "android.hidl.base@1.0",
diff --git a/graphics/composer/2.3/IComposerClient.hal b/graphics/composer/2.3/IComposerClient.hal
index 089438e..dec3b25 100644
--- a/graphics/composer/2.3/IComposerClient.hal
+++ b/graphics/composer/2.3/IComposerClient.hal
@@ -16,6 +16,10 @@
 
 package android.hardware.graphics.composer@2.3;
 
+import android.hardware.graphics.common@1.1::RenderIntent;
+import android.hardware.graphics.common@1.1::PixelFormat;
+import android.hardware.graphics.common@1.2::ColorMode;
+import android.hardware.graphics.common@1.2::Dataspace;
 import android.hardware.graphics.composer@2.1::IComposerClient.Command;
 import @2.2::IComposerClient;
 import @2.1::Display;
@@ -87,6 +91,75 @@
                generates (Error error,
                           uint8_t port,
                           vec<uint8_t> data);
+    /**
+     * getReadbackBufferAttributes_2_3
+     * Returns the format which should be used when allocating a buffer for use by
+     * device readback as well as the dataspace in which its contents must be
+     * interpreted.
+     *
+     * The width and height of this buffer must be those of the currently-active
+     * display configuration, and the usage flags must consist of the following:
+     *   BufferUsage::CPU_READ | BufferUsage::GPU_TEXTURE |
+     *   BufferUsage::COMPOSER_OUTPUT
+     *
+     * The format and dataspace provided must be sufficient such that if a
+     * correctly-configured buffer is passed into setReadbackBuffer, filled by
+     * the device, and then displayed by the client as a full-screen buffer, the
+     * output of the display remains the same (subject to the note about protected
+     * content in the description of setReadbackBuffer).
+     *
+     * If the active configuration or color mode of this display has changed
+     * since a previous call to this function, it must be called again prior to
+     * setting a readback buffer such that the returned format and dataspace will
+     * be updated accordingly.
+     *
+     * Parameters:
+     * @param display - the display on which to create the layer.
+     *
+     * @return format - the format the client should use when allocating a device
+     *     readback buffer
+     * @return dataspace - the dataspace to use when interpreting the
+     *     contents of a device readback buffer
+     * @return error is NONE upon success. Otherwise,
+     *     BAD_DISPLAY when an invalid display handle was passed in.
+     *     UNSUPPORTED if not supported on underlying HAL
+     *
+     * See also:
+     *   setReadbackBuffer
+     *   getReadbackBufferFence
+     */
+    getReadbackBufferAttributes_2_3(Display display)
+        generates (Error error,
+                   PixelFormat format,
+                   Dataspace dataspace);
+
+    /**
+     * getClientTargetSupport_2_3
+     * Returns whether a client target with the given properties can be
+     * handled by the device.
+     *
+     * This function must return true for a client target with width and
+     * height equal to the active display configuration dimensions,
+     * PixelFormat::RGBA_8888, and Dataspace::UNKNOWN. It is not required to
+     * return true for any other configuration.
+     *
+     * @param display is the display to query.
+     * @param width is the client target width in pixels.
+     * @param height is the client target height in pixels.
+     * @param format is the client target format.
+     * @param dataspace is the client target dataspace, as described in
+     *     setLayerDataspace.
+     * @return error is NONE upon success. Otherwise,
+     *     BAD_DISPLAY when an invalid display handle was passed in.
+     *     UNSUPPORTED when the given configuration is not supported.
+     */
+    @callflow(next="*")
+    getClientTargetSupport_2_3(Display display,
+                               uint32_t width,
+                               uint32_t height,
+                               PixelFormat format,
+                               Dataspace dataspace)
+                    generates (Error error);
 
     /**
      * Executes commands from the input command message queue. Return values
@@ -113,4 +186,58 @@
                         bool outQueueChanged,
                         uint32_t outLength,
                         vec<handle> outHandles);
+
+    /**
+     * Returns the render intents supported by the specified display and color
+     * mode.
+     *
+     * For SDR color modes, RenderIntent::COLORIMETRIC must be supported. For
+     * HDR color modes, RenderIntent::TONE_MAP_COLORIMETRIC must be supported.
+     *
+     * @param display is the display to query.
+     * @param mode is the color mode to query.
+     * @return error is NONE upon success. Otherwise,
+     *     BAD_DISPLAY when an invalid display handle was passed in.
+     *     BAD_PARAMETER when an invalid color mode was passed in.
+     * @return intents is an array of render intents.
+     */
+    getRenderIntents_2_3(Display display, ColorMode mode)
+          generates (Error error,
+                     vec<RenderIntent> intents);
+
+    /**
+     * Returns the color modes supported on this display.
+     *
+     * All devices must support at least ColorMode::NATIVE.
+     *
+     * @param display is the display to query.
+     * @return error is NONE upon success. Otherwise,
+     *     BAD_DISPLAY when an invalid display handle was passed in.
+     * @return modes is an array of color modes.
+     */
+    getColorModes_2_3(Display display)
+           generates (Error error,
+                      vec<ColorMode> modes);
+
+    /**
+     * Sets the color mode and render intent of the given display.
+     *
+     * The color mode and render intent change must take effect on next
+     * presentDisplay.
+     *
+     * All devices must support at least ColorMode::NATIVE and
+     * RenderIntent::COLORIMETRIC, and displays are assumed to be in this mode
+     * upon hotplug.
+     *
+     * @param display is the display to which the color mode is set.
+     * @param mode is the color mode to set to.
+     * @param intent is the render intent to set to.
+     * @return error is NONE upon success. Otherwise,
+     *     BAD_DISPLAY when an invalid display handle was passed in.
+     *     BAD_PARAMETER when mode or intent is invalid
+     *     UNSUPPORTED when mode or intent is not supported on this
+     *         display.
+     */
+    setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent)
+          generates (Error error);
 };
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index 3f7b2c9..6c95a1f 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -34,6 +34,7 @@
 namespace V2_3 {
 
 using android::hardware::MessageQueue;
+using android::hardware::graphics::common::V1_2::Dataspace;
 using android::hardware::graphics::composer::V2_1::Error;
 using android::hardware::graphics::composer::V2_1::IComposerCallback;
 using android::hardware::graphics::composer::V2_1::Layer;
@@ -43,6 +44,16 @@
 // units of uint32_t's.
 class CommandWriterBase : public V2_2::CommandWriterBase {
    public:
+    void setLayerDataspace(Dataspace dataspace) {
+        setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
+    }
+
+    void setClientTarget(uint32_t slot, const native_handle_t* target, int acquireFence,
+                         Dataspace dataspace, const std::vector<IComposerClient::Rect>& damage) {
+        setClientTargetInternal(slot, target, acquireFence, static_cast<int32_t>(dataspace),
+                                damage);
+    }
+
     CommandWriterBase(uint32_t initialMaxSize) : V2_2::CommandWriterBase(initialMaxSize) {}
 
     static constexpr uint16_t kSetLayerColorTransformLength = 16;
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 c805472..f9d6774 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
@@ -38,6 +38,41 @@
 template <typename Interface, typename Hal>
 class ComposerClientImpl : public V2_2::hal::detail::ComposerClientImpl<Interface, Hal> {
    public:
+    Return<Error> setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) override {
+        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 {
+        std::vector<RenderIntent> intents;
+        Error err = mHal->getRenderIntents_2_3(display, mode, &intents);
+        hidl_cb(err, intents);
+        return Void();
+    }
+
+    Return<void> getColorModes_2_3(Display display,
+                                   IComposerClient::getColorModes_2_3_cb hidl_cb) override {
+        hidl_vec<ColorMode> modes;
+        Error err = mHal->getColorModes_2_3(display, &modes);
+        hidl_cb(err, modes);
+        return Void();
+    }
+
+    Return<void> getReadbackBufferAttributes_2_3(
+        Display display, IComposerClient::getReadbackBufferAttributes_2_3_cb hidl_cb) override {
+        PixelFormat format = PixelFormat::RGB_888;
+        Dataspace dataspace = Dataspace::UNKNOWN;
+        Error error = mHal->getReadbackBufferAttributes_2_3(display, &format, &dataspace);
+        hidl_cb(error, format, dataspace);
+        return Void();
+    }
+
+    Return<Error> getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
+                                             PixelFormat format, Dataspace dataspace) override {
+        Error err = mHal->getClientTargetSupport_2_3(display, width, height, format, dataspace);
+        return err;
+    }
+
     static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {
         auto client = std::make_unique<ComposerClientImpl>(hal);
         return client->init() ? std::move(client) : nullptr;
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 0f6205a..27efc2b 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
@@ -25,12 +25,50 @@
 namespace V2_3 {
 namespace hal {
 
+using common::V1_1::PixelFormat;
+using common::V1_1::RenderIntent;
+using common::V1_2::ColorMode;
+using common::V1_2::Dataspace;
 using V2_1::Display;
 using V2_1::Error;
 using V2_1::Layer;
 
 class ComposerHal : public V2_2::hal::ComposerHal {
    public:
+    Error setColorMode_2_2(Display display, common::V1_1::ColorMode mode,
+                           RenderIntent intent) override {
+        return setColorMode_2_3(display, static_cast<ColorMode>(mode), intent);
+    }
+
+    Error getColorModes_2_2(Display display, hidl_vec<common::V1_1::ColorMode>* outModes) override {
+        return getColorModes_2_3(display, reinterpret_cast<hidl_vec<ColorMode>*>(outModes));
+    }
+
+    Error getClientTargetSupport_2_2(Display display, uint32_t width, uint32_t height,
+                                     common::V1_1::PixelFormat format,
+                                     common::V1_1::Dataspace dataspace) override {
+        return getClientTargetSupport_2_3(display, width, height, static_cast<PixelFormat>(format),
+                                          static_cast<Dataspace>(dataspace));
+    }
+
+    Error getReadbackBufferAttributes(Display display, common::V1_1::PixelFormat* outFormat,
+                                      common::V1_1::Dataspace* outDataspace) override {
+        return getReadbackBufferAttributes_2_3(display, reinterpret_cast<PixelFormat*>(outFormat),
+                                               reinterpret_cast<Dataspace*>(outDataspace));
+    }
+
+    virtual Error setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) = 0;
+
+    virtual Error getRenderIntents_2_3(Display display, ColorMode mode,
+                                       std::vector<RenderIntent>* outIntents) = 0;
+
+    virtual Error getColorModes_2_3(Display display, hidl_vec<ColorMode>* outModes) = 0;
+
+    virtual Error getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
+                                             PixelFormat format, Dataspace dataspace) = 0;
+    virtual Error getReadbackBufferAttributes_2_3(Display display, PixelFormat* outFormat,
+                                                  Dataspace* outDataspace) = 0;
+
     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;
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 ed1878b..df68f58 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
@@ -34,6 +34,10 @@
 
 namespace detail {
 
+using common::V1_1::PixelFormat;
+using common::V1_1::RenderIntent;
+using common::V1_2::ColorMode;
+using common::V1_2::Dataspace;
 using V2_1::Display;
 using V2_1::Error;
 
@@ -41,6 +45,32 @@
 template <typename Hal>
 class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> {
    public:
+    Error setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) override {
+        return setColorMode_2_2(display, static_cast<common::V1_1::ColorMode>(mode), intent);
+    }
+
+    Error getRenderIntents_2_3(Display display, ColorMode mode,
+                               std::vector<RenderIntent>* outIntents) override {
+        return getRenderIntents(display, static_cast<common::V1_1::ColorMode>(mode), outIntents);
+    }
+
+    Error getColorModes_2_3(Display display, hidl_vec<ColorMode>* outModes) override {
+        return getColorModes_2_2(display,
+                                 reinterpret_cast<hidl_vec<common::V1_1::ColorMode>*>(outModes));
+    }
+
+    Error getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
+                                     PixelFormat format, Dataspace dataspace) override {
+        return getClientTargetSupport_2_2(display, width, height, format,
+                                          static_cast<common::V1_1::Dataspace>(dataspace));
+    }
+
+    Error getReadbackBufferAttributes_2_3(Display display, PixelFormat* outFormat,
+                                          Dataspace* outDataspace) override {
+        return getReadbackBufferAttributes(
+            display, outFormat, reinterpret_cast<common::V1_1::Dataspace*>(outDataspace));
+    }
+
     Error getDisplayIdentificationData(Display display, uint8_t* outPort,
                                        std::vector<uint8_t>* outData) override {
         if (!mDispatch.getDisplayIdentificationData) {
@@ -96,6 +126,11 @@
     using BaseType2_2 = V2_2::passthrough::detail::HwcHalImpl<Hal>;
     using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
     using BaseType2_1::mDevice;
+    using BaseType2_2::getClientTargetSupport_2_2;
+    using BaseType2_2::getColorModes_2_2;
+    using BaseType2_2::getReadbackBufferAttributes;
+    using BaseType2_2::getRenderIntents;
+    using BaseType2_2::setColorMode_2_2;
 };
 
 }  // namespace detail
diff --git a/graphics/composer/2.3/utils/vts/ComposerVts.cpp b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
index f1d3a50..656c8c4 100644
--- a/graphics/composer/2.3/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
@@ -45,6 +45,10 @@
     return client;
 }
 
+sp<IComposerClient> ComposerClient::getRaw() const {
+    return mClient;
+}
+
 bool ComposerClient::getDisplayIdentificationData(Display display, uint8_t* outPort,
                                                   std::vector<uint8_t>* outData) {
     bool supported = true;
@@ -64,6 +68,46 @@
     return supported;
 }
 
+std::vector<ColorMode> ComposerClient::getColorModes_2_3(Display display) {
+    std::vector<ColorMode> modes;
+    mClient->getColorModes_2_3(display, [&](const auto& tmpError, const auto& tmpModes) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get color modes";
+        modes = tmpModes;
+    });
+    return modes;
+}
+
+void ComposerClient::setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) {
+    Error error = mClient->setColorMode_2_3(display, mode, intent);
+    ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set color mode";
+}
+
+std::vector<RenderIntent> ComposerClient::getRenderIntents_2_3(Display display, ColorMode mode) {
+    std::vector<RenderIntent> intents;
+    mClient->getRenderIntents_2_3(display, mode, [&](const auto& tmpError, const auto& tmpIntents) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get render intents";
+        intents = tmpIntents;
+    });
+    return intents;
+}
+
+void ComposerClient::getReadbackBufferAttributes_2_3(Display display, PixelFormat* outPixelFormat,
+                                                     Dataspace* outDataspace) {
+    mClient->getReadbackBufferAttributes_2_3(
+        display,
+        [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
+            *outPixelFormat = tmpOutPixelFormat;
+            *outDataspace = tmpOutDataspace;
+        });
+}
+
+bool ComposerClient::getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
+                                                PixelFormat format, Dataspace dataspace) {
+    Error error = mClient->getClientTargetSupport_2_3(display, width, height, format, dataspace);
+    return error == Error::NONE;
+}
+
 }  // 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 103b85a..ec1a2a1 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
@@ -32,6 +32,10 @@
 namespace V2_3 {
 namespace vts {
 
+using common::V1_1::PixelFormat;
+using common::V1_1::RenderIntent;
+using common::V1_2::ColorMode;
+using common::V1_2::Dataspace;
 using V2_1::Display;
 using V2_3::IComposer;
 using V2_3::IComposerClient;
@@ -59,9 +63,23 @@
     explicit ComposerClient(const sp<IComposerClient>& client)
         : V2_2::vts::ComposerClient(client), mClient(client) {}
 
+    sp<IComposerClient> getRaw() const;
+
     bool getDisplayIdentificationData(Display display, uint8_t* outPort,
                                       std::vector<uint8_t>* outData);
 
+    std::vector<ColorMode> getColorModes_2_3(Display display);
+
+    void setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent);
+
+    std::vector<RenderIntent> getRenderIntents_2_3(Display display, ColorMode mode);
+
+    void getReadbackBufferAttributes_2_3(Display display, PixelFormat* outPixelFormat,
+                                         Dataspace* outDataspace);
+
+    bool getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
+                                    PixelFormat format, Dataspace dataspace);
+
    private:
     const sp<IComposerClient> mClient;
 };
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index 1030ddc..3ca21aa 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -33,6 +33,11 @@
 namespace vts {
 namespace {
 
+using common::V1_1::PixelFormat;
+using common::V1_1::RenderIntent;
+using common::V1_2::ColorMode;
+using common::V1_2::Dataspace;
+
 // Test environment for graphics.composer
 class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
    public:
@@ -64,6 +69,8 @@
         // assume the first display is primary and is never removed
         mPrimaryDisplay = waitForFirstDisplay();
 
+        mInvalidDisplayId = GetInvalidDisplayId();
+
         // explicitly disable vsync
         mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
         mComposerCallback->setVsyncAllowed(false);
@@ -80,6 +87,22 @@
         }
     }
 
+    // returns an invalid display id (one that has not been registered to a
+    // display.  Currently assuming that a device will never have close to
+    // std::numeric_limit<uint64_t>::max() displays registered while running tests
+    Display GetInvalidDisplayId() {
+        std::vector<Display> validDisplays = mComposerCallback->getDisplays();
+        uint64_t id = std::numeric_limits<uint64_t>::max();
+        while (id > 0) {
+            if (std::find(validDisplays.begin(), validDisplays.end(), id) == validDisplays.end()) {
+                return id;
+            }
+            id--;
+        }
+
+        return 0;
+    }
+
     void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
 
     // use the slot count usually set by SF
@@ -90,6 +113,7 @@
     sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
     // the first display and is assumed never to be removed
     Display mPrimaryDisplay;
+    Display mInvalidDisplayId;
     std::unique_ptr<CommandWriterBase> mWriter;
     std::unique_ptr<V2_1::vts::TestCommandReader> mReader;
 
@@ -128,6 +152,185 @@
 }
 
 /**
+ * TestIComposerClient::getReadbackBufferAttributes_2_3
+ */
+TEST_F(GraphicsComposerHidlTest, GetReadbackBufferAttributes_2_3) {
+    Dataspace dataspace;
+    PixelFormat pixelFormat;
+
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferAttributes_2_3(
+        mPrimaryDisplay, &pixelFormat, &dataspace));
+}
+
+/**
+ * Test IComposerClient::getClientTargetSupport_2_3
+ */
+TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_3) {
+    std::vector<V2_1::Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
+    for (auto config : configs) {
+        int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+                                                             IComposerClient::Attribute::WIDTH);
+        int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+                                                              IComposerClient::Attribute::HEIGHT);
+        ASSERT_LT(0, width);
+        ASSERT_LT(0, height);
+
+        mComposerClient->setActiveConfig(mPrimaryDisplay, config);
+
+        ASSERT_TRUE(mComposerClient->getClientTargetSupport_2_3(
+            mPrimaryDisplay, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN));
+    }
+}
+/**
+ * Test IComposerClient::getClientTargetSupport_2_3
+ *
+ * Test that IComposerClient::getClientTargetSupport_2_3 returns
+ * Error::BAD_DISPLAY when passed in an invalid display handle
+ */
+
+TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_3BadDisplay) {
+    std::vector<V2_1::Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
+    for (auto config : configs) {
+        int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+                                                             IComposerClient::Attribute::WIDTH);
+        int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+                                                              IComposerClient::Attribute::HEIGHT);
+        ASSERT_LT(0, width);
+        ASSERT_LT(0, height);
+
+        mComposerClient->setActiveConfig(mPrimaryDisplay, config);
+
+        Error error = mComposerClient->getRaw()->getClientTargetSupport_2_3(
+            mInvalidDisplayId, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN);
+
+        EXPECT_EQ(Error::BAD_DISPLAY, error);
+    }
+}
+
+/**
+ * Test IComposerClient::getRenderIntents_2_3
+ */
+TEST_F(GraphicsComposerHidlTest, GetRenderIntents_2_3) {
+    std::vector<ColorMode> modes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
+    for (auto mode : modes) {
+        std::vector<RenderIntent> intents =
+            mComposerClient->getRenderIntents_2_3(mPrimaryDisplay, mode);
+
+        bool isHdr;
+        switch (mode) {
+            case ColorMode::BT2100_PQ:
+            case ColorMode::BT2100_HLG:
+                isHdr = true;
+                break;
+            default:
+                isHdr = false;
+                break;
+        }
+        RenderIntent requiredIntent =
+            isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
+
+        auto iter = std::find(intents.cbegin(), intents.cend(), requiredIntent);
+        EXPECT_NE(intents.cend(), iter);
+    }
+}
+
+/*
+ * Test IComposerClient::getRenderIntents_2_3
+ *
+ * Test that IComposerClient::getRenderIntents_2_3 returns Error::BAD_DISPLAY when
+ * passed an invalid display handle
+ */
+TEST_F(GraphicsComposerHidlTest, GetRenderIntents_2_3BadDisplay) {
+    std::vector<ColorMode> modes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
+    for (auto mode : modes) {
+        mComposerClient->getRaw()->getRenderIntents_2_3(
+            mInvalidDisplayId, mode,
+            [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_DISPLAY, tmpError); });
+    }
+}
+
+/*
+ * Test IComposerClient::getRenderIntents_2_3
+ *
+ * Test that IComposerClient::getRenderIntents_2_3 returns Error::BAD_PARAMETER when
+ * pased either an invalid Color mode or an invalid Render Intent
+ */
+TEST_F(GraphicsComposerHidlTest, GetRenderIntents_2_3BadParameter) {
+    mComposerClient->getRaw()->getRenderIntents_2_3(
+        mPrimaryDisplay, static_cast<ColorMode>(-1),
+        [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_PARAMETER, tmpError); });
+}
+
+/**
+ * IComposerClient::getColorModes_2_3
+ */
+TEST_F(GraphicsComposerHidlTest, GetColorModes_2_3) {
+    std::vector<ColorMode> colorModes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
+
+    auto native = std::find(colorModes.cbegin(), colorModes.cend(), ColorMode::NATIVE);
+    ASSERT_NE(colorModes.cend(), native);
+}
+
+/*
+ * Test IComposerClient::getColorModes_2_3
+ *
+ * Test that IComposerClient::getColorModes_2_3 returns Error::BAD_DISPLAY when
+ * passed an invalid display handle
+ */
+TEST_F(GraphicsComposerHidlTest, GetColorMode_2_3BadDisplay) {
+    mComposerClient->getRaw()->getColorModes_2_3(
+        mInvalidDisplayId,
+        [&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_DISPLAY, tmpError); });
+}
+
+/**
+ * IComposerClient::setColorMode_2_3
+ */
+TEST_F(GraphicsComposerHidlTest, SetColorMode_2_3) {
+    std::vector<ColorMode> colorModes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
+    for (auto mode : colorModes) {
+        std::vector<RenderIntent> intents =
+            mComposerClient->getRenderIntents_2_3(mPrimaryDisplay, mode);
+        for (auto intent : intents) {
+            ASSERT_NO_FATAL_FAILURE(
+                mComposerClient->setColorMode_2_3(mPrimaryDisplay, mode, intent));
+        }
+    }
+
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode_2_3(mPrimaryDisplay, ColorMode::NATIVE,
+                                                              RenderIntent::COLORIMETRIC));
+}
+
+/*
+ * Test IComposerClient::setColorMode_2_3
+ *
+ * Test that IComposerClient::setColorMode_2_3 returns an Error::BAD_DISPLAY
+ * when passed an invalid display handle
+ */
+TEST_F(GraphicsComposerHidlTest, SetColorMode_2_3BadDisplay) {
+    Error error = mComposerClient->getRaw()->setColorMode_2_3(mInvalidDisplayId, ColorMode::NATIVE,
+                                                              RenderIntent::COLORIMETRIC);
+
+    ASSERT_EQ(Error::BAD_DISPLAY, error);
+}
+
+/*
+ * Test IComposerClient::setColorMode_2_3
+ *
+ * Test that IComposerClient::setColorMode_2_3 returns Error::BAD_PARAMETER when
+ * passed an invalid Color mode or an invalid render intent
+ */
+TEST_F(GraphicsComposerHidlTest, SetColorMode_2_3BadParameter) {
+    Error colorModeError = mComposerClient->getRaw()->setColorMode_2_3(
+        mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
+    EXPECT_EQ(Error::BAD_PARAMETER, colorModeError);
+
+    Error renderIntentError = mComposerClient->getRaw()->setColorMode_2_3(
+        mPrimaryDisplay, ColorMode::NATIVE, static_cast<RenderIntent>(-1));
+    EXPECT_EQ(Error::BAD_PARAMETER, renderIntentError);
+}
+
+/**
  * Test IComposerClient::Command::SET_LAYER_COLOR_TRANSFORM.
  * TODO Add color to the layer, use matrix to keep only red component,
  * and check.
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 18f35c1..ffba45c 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",
     ],
@@ -55,6 +56,7 @@
         "android.hardware.neuralnetworks@1.2",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "libgmock",
         "libhidlmemory",
         "libneuralnetworks_utils",
         "VtsHalNeuralnetworksTest_utils",
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index b8046c7..cc19978 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) {
@@ -66,7 +67,7 @@
 // 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 +76,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 +177,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 +229,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 +280,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..a1c0f1f 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -31,6 +31,7 @@
         "android.hardware.neuralnetworks@1.2",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "libgmock",
         "libhidlmemory",
         "libneuralnetworks_utils",
         "VtsHalNeuralnetworksTest_utils",
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTests.cpp b/neuralnetworks/1.1/vts/functional/GeneratedTests.cpp
index 95c2b1a..1f49904 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,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 generated_tests::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.1/vts/functional/Models.h b/neuralnetworks/1.1/vts/functional/Models.h
index cc0fac1..62bc95e 100644
--- a/neuralnetworks/1.1/vts/functional/Models.h
+++ b/neuralnetworks/1.1/vts/functional/Models.h
@@ -31,7 +31,7 @@
 namespace vts {
 namespace functional {
 
-using MixedTypedExample = test_helper::MixedTypedExampleType;
+using MixedTypedExample = test_helper::MixedTypedExample;
 
 #define FOR_EACH_TEST_MODEL(FN)                                  \
     FN(add)                                                      \
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.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 2dc19cc..09d0dc3 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -31,6 +31,7 @@
         "android.hardware.neuralnetworks@1.2",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "libgmock",
         "libhidlmemory",
         "libneuralnetworks_utils",
         "VtsHalNeuralnetworksTest_utils",
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTests.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTests.cpp
index 662c531..e87fa6b 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,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 generated_tests::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.2/vts/functional/Models.h b/neuralnetworks/1.2/vts/functional/Models.h
index f3769bc..2d512fe 100644
--- a/neuralnetworks/1.2/vts/functional/Models.h
+++ b/neuralnetworks/1.2/vts/functional/Models.h
@@ -32,7 +32,7 @@
 namespace vts {
 namespace functional {
 
-using MixedTypedExample = test_helper::MixedTypedExampleType;
+using MixedTypedExample = test_helper::MixedTypedExample;
 
 #define FOR_EACH_TEST_MODEL(FN)                                  \
     FN(add)                                                      \
@@ -243,6 +243,7 @@
     FN(pad_float_1)                                              \
     FN(pad_float_1_relaxed)                                      \
     FN(pad_relaxed)                                              \
+    FN(random_multinomial)                                       \
     FN(relu1_float_1)                                            \
     FN(relu1_float_1_relaxed)                                    \
     FN(relu1_float_2)                                            \
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/power/stats/1.0/IPowerStats.hal b/power/stats/1.0/IPowerStats.hal
index d75e170..b5b3cc9 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,10 @@
      * @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);
 };
diff --git a/power/stats/1.0/types.hal b/power/stats/1.0/types.hal
index 826c29b..703e542 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 {
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..94cd6e5 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -79,6 +79,9 @@
     SensorsHidlEnvironmentBase* getEnvironment() override {
         return SensorsHidlEnvironmentV2_0::Instance();
     }
+
+    // Helper functions
+    void activateAllSensors(bool enable);
 };
 
 Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
@@ -437,6 +440,54 @@
                               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);
+}
+
 int main(int argc, char** argv) {
     ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironmentV2_0::Instance());
     ::testing::InitGoogleTest(&argc, argv);
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/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/update-base-files.sh b/update-base-files.sh
index 75d2be5..daaa530 100755
--- a/update-base-files.sh
+++ b/update-base-files.sh
@@ -36,6 +36,9 @@
 hidl-gen $options \
          -o $ANDROID_BUILD_TOP/system/core/include/system/graphics-base-v1.1.h \
          android.hardware.graphics.common@1.1
+hidl-gen $options \
+         -o $ANDROID_BUILD_TOP/system/core/include/system/graphics-base-v1.2.h \
+         android.hardware.graphics.common@1.2
 
 # system/media
 hidl-gen $options \
diff --git a/update-makefiles.sh b/update-makefiles.sh
index b7e4235..14c5b01 100755
--- a/update-makefiles.sh
+++ b/update-makefiles.sh
@@ -1,4 +1,12 @@
 #!/bin/bash
+# Script to update Android make-files for HAL and VTS modules.
+
+set -e
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+    echo "Missing ANDROID_BUILD_TOP env variable. Run 'lunch' first."
+    exit 1
+fi
 
 source $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh
 
@@ -6,3 +14,8 @@
   "android.hardware:hardware/interfaces" \
   "android.hidl:system/libhidl/transport"
 
+echo "Updating files at $ANDROID_BUILD_TOP/test/vts-testcase/hal"
+pushd $ANDROID_BUILD_TOP/test/vts-testcase/hal
+./script/update_makefiles.py
+popd
+
diff --git a/wifi/1.3/default/Android.mk b/wifi/1.3/default/Android.mk
index 541e5f0..e05d2f0 100644
--- a/wifi/1.3/default/Android.mk
+++ b/wifi/1.3/default/Android.mk
@@ -30,6 +30,8 @@
 ifdef WIFI_HIDL_FEATURE_DISABLE_AP
 LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP
 endif
+# Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed.
+LOCAL_CFLAGS += -Wno-error=implicit-fallthrough
 LOCAL_SRC_FILES := \
     hidl_struct_util.cpp \
     hidl_sync_util.cpp \
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..0bba096
--- /dev/null
+++ b/wifi/supplicant/1.2/ISupplicantStaNetwork.hal
@@ -0,0 +1,232 @@
+/*
+ * 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,
+    };
+
+    /**
+     * 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);
+
+    /**
+     * 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);
+};