Merge "Convert Vehicle Property to integer"
diff --git a/audio/common/2.0/types.hal b/audio/common/2.0/types.hal
index eec4ac2..63d66db 100644
--- a/audio/common/2.0/types.hal
+++ b/audio/common/2.0/types.hal
@@ -233,7 +233,8 @@
     SBC                 = 0x1F000000UL,
     APTX                = 0x20000000UL,
     APTX_HD             = 0x21000000UL,
-    LDAC                = 0x22000000UL,
+    AC4                 = 0x22000000UL,
+    LDAC                = 0x23000000UL,
     MAIN_MASK           = 0xFF000000UL, /* Deprecated */
     SUB_MASK            = 0x00FFFFFFUL,
 
@@ -431,6 +432,9 @@
     IN_MONO   = IN_FRONT,
     IN_STEREO = (IN_LEFT | IN_RIGHT),
     IN_FRONT_BACK = (IN_FRONT | IN_BACK),
+    IN_6 = (IN_LEFT | IN_RIGHT |
+            IN_FRONT | IN_BACK |
+            IN_LEFT_PROCESSED | IN_RIGHT_PROCESSED),
     IN_VOICE_UPLINK_MONO = (IN_VOICE_UPLINK | IN_MONO),
     IN_VOICE_DNLINK_MONO = (IN_VOICE_DNLINK | IN_MONO),
     IN_VOICE_CALL_MONO   = (IN_VOICE_UPLINK_MONO |
diff --git a/bluetooth/1.0/default/Android.bp b/bluetooth/1.0/default/Android.bp
index 32e5328..4af079e 100644
--- a/bluetooth/1.0/default/Android.bp
+++ b/bluetooth/1.0/default/Android.bp
@@ -35,9 +35,24 @@
     ],
 }
 
-cc_test_host {
+cc_test {
     name: "bluetooth-vendor-interface-unit-tests",
     srcs: [
+        "async_fd_watcher.cc",
+        "test/async_fd_watcher_unittest.cc",
+    ],
+    local_include_dirs: [
+        "test",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+}
+
+cc_test_host {
+    name: "bluetooth-address-unit-tests",
+    srcs: [
         "bluetooth_address.cc",
         "test/bluetooth_address_test.cc",
         "test/properties.cc",
diff --git a/bluetooth/1.0/default/async_fd_watcher.cc b/bluetooth/1.0/default/async_fd_watcher.cc
index 636b4b6..9cd86f1 100644
--- a/bluetooth/1.0/default/async_fd_watcher.cc
+++ b/bluetooth/1.0/default/async_fd_watcher.cc
@@ -50,6 +50,20 @@
   return 0;
 }
 
+int AsyncFdWatcher::ConfigureTimeout(
+    const std::chrono::milliseconds timeout,
+    const TimeoutCallback& on_timeout_callback) {
+  // Add timeout and callback
+  {
+    std::unique_lock<std::mutex> guard(timeout_mutex_);
+    timeout_cb_ = on_timeout_callback;
+    timeout_ms_ = timeout;
+  }
+
+  notifyThread();
+  return 0;
+}
+
 void AsyncFdWatcher::StopWatchingFileDescriptor() { stopThread(); }
 
 AsyncFdWatcher::~AsyncFdWatcher() {}
@@ -86,6 +100,11 @@
     read_fd_ = -1;
   }
 
+  {
+    std::unique_lock<std::mutex> guard(timeout_mutex_);
+    timeout_cb_ = nullptr;
+  }
+
   return 0;
 }
 
@@ -104,21 +123,37 @@
     FD_SET(notification_listen_fd_, &read_fds);
     FD_SET(read_fd_, &read_fds);
 
-    // Wait until there is data available to read on some FD
-    int nfds = std::max(notification_listen_fd_, read_fd_);
-    int retval = select(nfds + 1, &read_fds, NULL, NULL, NULL);
-    if (retval <= 0) continue;  // there was some error or a timeout
+    struct timeval timeout;
+    struct timeval* timeout_ptr = NULL;
+    if (timeout_ms_ > std::chrono::milliseconds(0)) {
+      timeout.tv_sec = timeout_ms_.count() / 1000;
+      timeout.tv_usec = (timeout_ms_.count() % 1000) * 1000;
+      timeout_ptr = &timeout;
+    }
 
-    // Read data from the notification FD
+    // Wait until there is data available to read on some FD.
+    int nfds = std::max(notification_listen_fd_, read_fd_);
+    int retval = select(nfds + 1, &read_fds, NULL, NULL, timeout_ptr);
+
+    // There was some error.
+    if (retval < 0) continue;
+
+    // Timeout.
+    if (retval == 0) {
+      std::unique_lock<std::mutex> guard(timeout_mutex_);
+      if (timeout_ms_ > std::chrono::milliseconds(0) && timeout_cb_)
+        timeout_cb_();
+      continue;
+    }
+
+    // Read data from the notification FD.
     if (FD_ISSET(notification_listen_fd_, &read_fds)) {
       char buffer[] = {0};
       TEMP_FAILURE_RETRY(read(notification_listen_fd_, buffer, 1));
+      continue;
     }
 
-    // Make sure we're still running
-    if (!running_) break;
-
-    // Invoke the data ready callback if appropriate
+    // Invoke the data ready callback if appropriate.
     if (FD_ISSET(read_fd_, &read_fds)) {
       std::unique_lock<std::mutex> guard(internal_mutex_);
       if (cb_) cb_(read_fd_);
diff --git a/bluetooth/1.0/default/async_fd_watcher.h b/bluetooth/1.0/default/async_fd_watcher.h
index 1e4da8c..d6e112f 100644
--- a/bluetooth/1.0/default/async_fd_watcher.h
+++ b/bluetooth/1.0/default/async_fd_watcher.h
@@ -26,6 +26,7 @@
 namespace implementation {
 
 using ReadCallback = std::function<void(int)>;
+using TimeoutCallback = std::function<void(void)>;
 
 class AsyncFdWatcher {
  public:
@@ -34,6 +35,8 @@
 
   int WatchFdForNonBlockingReads(int file_descriptor,
                                  const ReadCallback& on_read_fd_ready_callback);
+  int ConfigureTimeout(const std::chrono::milliseconds timeout,
+                       const TimeoutCallback& on_timeout_callback);
   void StopWatchingFileDescriptor();
 
  private:
@@ -48,11 +51,14 @@
   std::atomic_bool running_{false};
   std::thread thread_;
   std::mutex internal_mutex_;
+  std::mutex timeout_mutex_;
 
   int read_fd_;
   int notification_listen_fd_;
   int notification_write_fd_;
   ReadCallback cb_;
+  TimeoutCallback timeout_cb_;
+  std::chrono::milliseconds timeout_ms_;
 };
 
 
diff --git a/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc b/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc
new file mode 100644
index 0000000..c21acb8
--- /dev/null
+++ b/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc
@@ -0,0 +1,295 @@
+//
+// Copyright 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "async_fd_watcher.h"
+#include <gtest/gtest.h>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+class AsyncFdWatcherSocketTest : public ::testing::Test {
+ public:
+  static const uint16_t kPort = 6111;
+  static const size_t kBufferSize = 16;
+
+  bool CheckBufferEquals() {
+    return strcmp(server_buffer_, client_buffer_) == 0;
+  }
+
+ protected:
+  int StartServer() {
+    ALOGD("%s", __func__);
+    struct sockaddr_in serv_addr;
+    int fd = socket(AF_INET, SOCK_STREAM, 0);
+    EXPECT_FALSE(fd < 0);
+
+    memset(&serv_addr, 0, sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    serv_addr.sin_port = htons(kPort);
+    int reuse_flag = 1;
+    EXPECT_FALSE(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag,
+                            sizeof(reuse_flag)) < 0);
+    EXPECT_FALSE(bind(fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) <
+                 0);
+
+    ALOGD("%s before listen", __func__);
+    listen(fd, 1);
+    return fd;
+  }
+
+  int AcceptConnection(int fd) {
+    ALOGD("%s", __func__);
+    struct sockaddr_in cli_addr;
+    memset(&cli_addr, 0, sizeof(cli_addr));
+    socklen_t clilen = sizeof(cli_addr);
+
+    int connection_fd = accept(fd, (struct sockaddr*)&cli_addr, &clilen);
+    EXPECT_FALSE(connection_fd < 0);
+
+    return connection_fd;
+  }
+
+  void ReadIncomingMessage(int fd) {
+    ALOGD("%s", __func__);
+    int n = TEMP_FAILURE_RETRY(read(fd, server_buffer_, kBufferSize - 1));
+    EXPECT_FALSE(n < 0);
+
+    if (n == 0)  // got EOF
+      ALOGD("%s: EOF", __func__);
+    else
+      ALOGD("%s: Got something", __func__);
+      n = write(fd, "1", 1);
+  }
+
+  void SetUp() override {
+    ALOGD("%s", __func__);
+    memset(server_buffer_, 0, kBufferSize);
+    memset(client_buffer_, 0, kBufferSize);
+  }
+
+  void ConfigureServer() {
+    socket_fd_ = StartServer();
+
+    conn_watcher_.WatchFdForNonBlockingReads(socket_fd_, [this](int fd) {
+      int connection_fd = AcceptConnection(fd);
+      ALOGD("%s: Conn_watcher fd = %d", __func__, fd);
+
+      conn_watcher_.ConfigureTimeout(std::chrono::seconds(0), [this]() { bool connection_timeout_cleared = false; ASSERT_TRUE(connection_timeout_cleared); });
+
+      ALOGD("%s: 3", __func__);
+      async_fd_watcher_.WatchFdForNonBlockingReads(
+          connection_fd, [this](int fd) { ReadIncomingMessage(fd); });
+
+      // Time out if it takes longer than a second.
+      SetTimeout(std::chrono::seconds(1));
+    });
+    conn_watcher_.ConfigureTimeout(std::chrono::seconds(1), [this]() { bool connection_timeout = true; ASSERT_FALSE(connection_timeout); });
+  }
+
+  void CleanUpServer() {
+    async_fd_watcher_.StopWatchingFileDescriptor();
+    conn_watcher_.StopWatchingFileDescriptor();
+    close(socket_fd_);
+  }
+
+  void TearDown() override {
+    ALOGD("%s 3", __func__);
+    EXPECT_TRUE(CheckBufferEquals());
+  }
+
+  void OnTimeout() {
+    ALOGD("%s", __func__);
+    timed_out_ = true;
+  }
+
+  void ClearTimeout() {
+    ALOGD("%s", __func__);
+    timed_out_ = false;
+  }
+
+  bool TimedOut() {
+    ALOGD("%s %d", __func__, timed_out_? 1 : 0);
+    return timed_out_;
+  }
+
+  void SetTimeout(std::chrono::milliseconds timeout_ms) {
+    ALOGD("%s", __func__);
+    async_fd_watcher_.ConfigureTimeout(timeout_ms, [this]() { OnTimeout(); });
+    ClearTimeout();
+  }
+
+  int ConnectClient() {
+    ALOGD("%s", __func__);
+    int socket_cli_fd = socket(AF_INET, SOCK_STREAM, 0);
+    EXPECT_FALSE(socket_cli_fd < 0);
+
+    struct sockaddr_in serv_addr;
+    memset((void*)&serv_addr, 0, sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    serv_addr.sin_port = htons(kPort);
+
+    int result =
+        connect(socket_cli_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+    EXPECT_FALSE(result < 0);
+
+    return socket_cli_fd;
+  }
+
+  void WriteFromClient(int socket_cli_fd) {
+    ALOGD("%s", __func__);
+    strcpy(client_buffer_, "1");
+    int n = write(socket_cli_fd, client_buffer_, strlen(client_buffer_));
+    EXPECT_TRUE(n > 0);
+  }
+
+  void AwaitServerResponse(int socket_cli_fd) {
+    ALOGD("%s", __func__);
+    int n = read(socket_cli_fd, client_buffer_, 1);
+    ALOGD("%s done", __func__);
+    EXPECT_TRUE(n > 0);
+  }
+
+ private:
+  AsyncFdWatcher async_fd_watcher_;
+  AsyncFdWatcher conn_watcher_;
+  int socket_fd_;
+  char server_buffer_[kBufferSize];
+  char client_buffer_[kBufferSize];
+  bool timed_out_;
+};
+
+// Use a single AsyncFdWatcher to signal a connection to the server socket.
+TEST_F(AsyncFdWatcherSocketTest, Connect) {
+  int socket_fd = StartServer();
+
+  AsyncFdWatcher conn_watcher;
+  conn_watcher.WatchFdForNonBlockingReads(socket_fd, [this](int fd) {
+    int connection_fd = AcceptConnection(fd);
+    close(connection_fd);
+  });
+
+  // Fail if the client doesn't connect within 1 second.
+  conn_watcher.ConfigureTimeout(std::chrono::seconds(1), [this]() {
+     bool connection_timeout = true;
+     ASSERT_FALSE(connection_timeout);
+  });
+
+  ConnectClient();
+  conn_watcher.StopWatchingFileDescriptor();
+  close(socket_fd);
+}
+
+// Use a single AsyncFdWatcher to signal a connection to the server socket.
+TEST_F(AsyncFdWatcherSocketTest, TimedOutConnect) {
+  int socket_fd = StartServer();
+  bool timed_out = false;
+  bool* timeout_ptr = &timed_out;
+
+  AsyncFdWatcher conn_watcher;
+  conn_watcher.WatchFdForNonBlockingReads(socket_fd, [this](int fd) {
+    int connection_fd = AcceptConnection(fd);
+    close(connection_fd);
+  });
+
+  // Set the timeout flag after 100ms.
+  conn_watcher.ConfigureTimeout(std::chrono::milliseconds(100), [this, timeout_ptr]() { *timeout_ptr = true; });
+  EXPECT_FALSE(timed_out);
+  sleep(1);
+  EXPECT_TRUE(timed_out);
+  conn_watcher.StopWatchingFileDescriptor();
+  close(socket_fd);
+}
+
+// Use two AsyncFdWatchers to set up a server socket.
+TEST_F(AsyncFdWatcherSocketTest, ClientServer) {
+  ConfigureServer();
+  int socket_cli_fd = ConnectClient();
+
+  WriteFromClient(socket_cli_fd);
+
+  AwaitServerResponse(socket_cli_fd);
+
+  close(socket_cli_fd);
+  CleanUpServer();
+}
+
+// Use two AsyncFdWatchers to set up a server socket, which times out.
+TEST_F(AsyncFdWatcherSocketTest, TimeOutTest) {
+  ConfigureServer();
+  int socket_cli_fd = ConnectClient();
+
+  while (!TimedOut()) sleep(1);
+
+  close(socket_cli_fd);
+  CleanUpServer();
+}
+
+// Use two AsyncFdWatchers to set up a server socket, which times out.
+TEST_F(AsyncFdWatcherSocketTest, RepeatedTimeOutTest) {
+  ConfigureServer();
+  int socket_cli_fd = ConnectClient();
+  ClearTimeout();
+
+  // Time out when there are no writes.
+  EXPECT_FALSE(TimedOut());
+  sleep(2);
+  EXPECT_TRUE(TimedOut());
+  ClearTimeout();
+
+  // Don't time out when there is a write.
+  WriteFromClient(socket_cli_fd);
+  AwaitServerResponse(socket_cli_fd);
+  EXPECT_FALSE(TimedOut());
+  ClearTimeout();
+
+  // Time out when the write is late.
+  sleep(2);
+  WriteFromClient(socket_cli_fd);
+  AwaitServerResponse(socket_cli_fd);
+  EXPECT_TRUE(TimedOut());
+  ClearTimeout();
+
+  // Time out when there is a pause after a write.
+  WriteFromClient(socket_cli_fd);
+  sleep(2);
+  AwaitServerResponse(socket_cli_fd);
+  EXPECT_TRUE(TimedOut());
+  ClearTimeout();
+
+  close(socket_cli_fd);
+  CleanUpServer();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index 5d9ae4d..3a4bc9c 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -369,9 +369,11 @@
 }
 
 int CameraModule::setCallbacks(const camera_module_callbacks_t *callbacks) {
-    int res;
+    int res = OK;
     ATRACE_BEGIN("camera_module->set_callbacks");
-    res = mModule->set_callbacks(callbacks);
+    if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
+        res = mModule->set_callbacks(callbacks);
+    }
     ATRACE_END();
     return res;
 }
diff --git a/camera/metadata/3.2/types.hal b/camera/metadata/3.2/types.hal
index ae70550..2b4b287 100644
--- a/camera/metadata/3.2/types.hal
+++ b/camera/metadata/3.2/types.hal
@@ -251,6 +251,8 @@
 
     ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
 
+    ANDROID_CONTROL_ENABLE_ZSL,
+
     ANDROID_CONTROL_END,
 
     ANDROID_DEMOSAIC_MODE = CameraMetadataSectionStart:ANDROID_DEMOSAIC_START,
@@ -923,6 +925,13 @@
 
 };
 
+enum CameraMetadataEnumAndroidControlEnableZsl : uint32_t {
+    ANDROID_CONTROL_ENABLE_ZSL_FALSE,
+
+    ANDROID_CONTROL_ENABLE_ZSL_TRUE,
+
+};
+
 enum CameraMetadataEnumAndroidDemosaicMode : uint32_t {
     ANDROID_DEMOSAIC_MODE_FAST,
 
diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp
index 1a34aa6..f1a66a8 100644
--- a/camera/provider/2.4/default/CameraProvider.cpp
+++ b/camera/provider/2.4/default/CameraProvider.cpp
@@ -184,13 +184,20 @@
     mModule = new CameraModule(rawModule);
     err = mModule->init();
     if (err != OK) {
-        ALOGE("Could not initialize camera HAL module: %d (%s)", err,
-            strerror(-err));
+        ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
         mModule.clear();
         return true;
     }
     ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
 
+    // Setup callback now because we are going to try openLegacy next
+    err = mModule->setCallbacks(this);
+    if (err != OK) {
+        ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
+        mModule.clear();
+        return true;
+    }
+
     mNumberOfLegacyCameras = mModule->getNumberOfCameras();
     for (int i = 0; i < mNumberOfLegacyCameras; i++) {
         char cameraId[kMaxCameraIdLen];
@@ -289,11 +296,9 @@
 
 // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
 Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback)  {
-    {
-        Mutex::Autolock _l(mCbLock);
-        mCallbacks = callback;
-    } // release lock here because HAL might send callbacks in setCallbacks call
-    return getHidlStatus(mModule->setCallbacks(this));
+    Mutex::Autolock _l(mCbLock);
+    mCallbacks = callback;
+    return Status::OK;
 }
 
 Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb)  {
@@ -320,8 +325,9 @@
 }
 
 Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
-        const hidl_string& /*cameraDeviceName*/, getCameraDeviceInterface_V1_x_cb /*_hidl_cb*/)  {
+        const hidl_string& /*cameraDeviceName*/, getCameraDeviceInterface_V1_x_cb _hidl_cb)  {
     // TODO implement after device 1.0 is implemented
+    _hidl_cb(Status::INTERNAL_ERROR, nullptr);
     return Void();
 }
 
diff --git a/camera/provider/2.4/default/service.cpp b/camera/provider/2.4/default/service.cpp
index 2723dee..9600559 100644
--- a/camera/provider/2.4/default/service.cpp
+++ b/camera/provider/2.4/default/service.cpp
@@ -20,6 +20,7 @@
 #include <CameraProvider.h>
 
 #include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
 #include <utils/StrongPointer.h>
 
 using android::hardware::configureRpcThreadpool;
@@ -32,6 +33,11 @@
 {
     const char instance[] = "legacy/0";
 
+    // TODO(b/34817742): use defaultServicePassthroughImplementation
+    // so that the toggle is implemented correctly
+    using ::android::hardware::details::blockIfBinderizationDisabled;
+    blockIfBinderizationDisabled(ICameraProvider::descriptor, instance);
+
     ALOGI("Camera provider Service is starting.");
 
     configureRpcThreadpool(1, true /* callerWillJoin */);
diff --git a/configstore/1.0/Android.bp b/configstore/1.0/Android.bp
new file mode 100644
index 0000000..06fcbd9
--- /dev/null
+++ b/configstore/1.0/Android.bp
@@ -0,0 +1,56 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.configstore@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.0",
+    srcs: [
+        "types.hal",
+        "ISurfaceFlingerConfigs.hal",
+    ],
+    out: [
+        "android/hardware/configstore/1.0/types.cpp",
+        "android/hardware/configstore/1.0/SurfaceFlingerConfigsAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.configstore@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.0",
+    srcs: [
+        "types.hal",
+        "ISurfaceFlingerConfigs.hal",
+    ],
+    out: [
+        "android/hardware/configstore/1.0/types.h",
+        "android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h",
+        "android/hardware/configstore/1.0/IHwSurfaceFlingerConfigs.h",
+        "android/hardware/configstore/1.0/BnHwSurfaceFlingerConfigs.h",
+        "android/hardware/configstore/1.0/BpHwSurfaceFlingerConfigs.h",
+        "android/hardware/configstore/1.0/BsSurfaceFlingerConfigs.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.configstore@1.0",
+    generated_sources: ["android.hardware.configstore@1.0_genc++"],
+    generated_headers: ["android.hardware.configstore@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.configstore@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hidl.base@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/configstore/1.0/Android.mk b/configstore/1.0/Android.mk
new file mode 100644
index 0000000..fd2718e
--- /dev/null
+++ b/configstore/1.0/Android.mk
@@ -0,0 +1,308 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.configstore@1.0-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hidl.base@1.0-java \
+
+
+#
+# Build types.hal (OptionalBool)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalBool.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalBool
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalInt32)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalInt32.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalInt32
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalInt64)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalInt64.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalInt64
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalString)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalString.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalString
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalUInt32)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalUInt32.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalUInt32
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalUInt64)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalUInt64.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalUInt64
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ISurfaceFlingerConfigs.hal
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/ISurfaceFlingerConfigs.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISurfaceFlingerConfigs.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::ISurfaceFlingerConfigs
+
+$(GEN): $(LOCAL_PATH)/ISurfaceFlingerConfigs.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.configstore@1.0-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android.hidl.base@1.0-java-static \
+
+
+#
+# Build types.hal (OptionalBool)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalBool.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalBool
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalInt32)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalInt32.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalInt32
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalInt64)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalInt64.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalInt64
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalString)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalString.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalString
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalUInt32)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalUInt32.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalUInt32
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (OptionalUInt64)
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/OptionalUInt64.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::types.OptionalUInt64
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ISurfaceFlingerConfigs.hal
+#
+GEN := $(intermediates)/android/hardware/configstore/V1_0/ISurfaceFlingerConfigs.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISurfaceFlingerConfigs.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.configstore@1.0::ISurfaceFlingerConfigs
+
+$(GEN): $(LOCAL_PATH)/ISurfaceFlingerConfigs.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/configstore/1.0/ISurfaceFlingerConfigs.hal b/configstore/1.0/ISurfaceFlingerConfigs.hal
new file mode 100644
index 0000000..97dc915
--- /dev/null
+++ b/configstore/1.0/ISurfaceFlingerConfigs.hal
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.configstore@1.0;
+
+interface ISurfaceFlingerConfigs {
+    vsyncEventPhaseOffsetNs() generates (OptionalInt64 value);
+};
diff --git a/configstore/1.0/default/Android.mk b/configstore/1.0/default/Android.mk
new file mode 100644
index 0000000..5de3451
--- /dev/null
+++ b/configstore/1.0/default/Android.mk
@@ -0,0 +1,40 @@
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.configstore@1.0-impl
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MODULE_RELATIVE_PATH := hw
+
+include $(LOCAL_PATH)/surfaceflinger.mk
+
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    libhidlbase \
+    libhidltransport \
+    libhwbinder \
+    libutils \
+    android.hardware.configstore@1.0 \
+    android.hidl.base@1.0
+
+include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.configstore@1.0-service
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_INIT_RC := android.hardware.configstore@1.0-service.rc
+LOCAL_SRC_FILES:= service.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libdl \
+    libutils \
+    libhidlbase \
+    libhidltransport \
+    libhwbinder \
+    android.hardware.configstore@1.0 \
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.cpp b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
new file mode 100644
index 0000000..fc75182
--- /dev/null
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
@@ -0,0 +1,33 @@
+#include "SurfaceFlingerConfigs.h"
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace configstore {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs follow.
+Return<void> SurfaceFlingerConfigs::vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) {
+#ifdef VSYNC_EVENT_PHASE_OFFSET_NS
+    _hidl_cb({true, VSYNC_EVENT_PHASE_OFFSET_NS});
+    LOG(INFO) << "vsync event phase offset ns =  " << VSYNC_EVENT_PHASE_OFFSET_NS;
+#else
+    _hidl_cb({false, 0});
+#endif
+    return Void();
+}
+
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+ISurfaceFlingerConfigs* HIDL_FETCH_ISurfaceFlingerConfigs(const char* /* name */) {
+    return new SurfaceFlingerConfigs();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace configstore
+}  // namespace hardware
+}  // namespace android
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.h b/configstore/1.0/default/SurfaceFlingerConfigs.h
new file mode 100644
index 0000000..5c754a0
--- /dev/null
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.h
@@ -0,0 +1,41 @@
+#ifndef ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
+#define ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
+
+#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace configstore {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
+using ::android::hardware::configstore::V1_0::OptionalBool;
+using ::android::hidl::base::V1_0::IBase;
+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 SurfaceFlingerConfigs : public ISurfaceFlingerConfigs {
+    // Methods from ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs follow.
+    Return<void> vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) override;
+
+    // Methods from ::android::hidl::base::V1_0::IBase follow.
+
+};
+
+extern "C" ISurfaceFlingerConfigs* HIDL_FETCH_ISurfaceFlingerConfigs(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace configstore
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
diff --git a/configstore/1.0/default/android.hardware.configstore@1.0-service.rc b/configstore/1.0/default/android.hardware.configstore@1.0-service.rc
new file mode 100644
index 0000000..2e303b0
--- /dev/null
+++ b/configstore/1.0/default/android.hardware.configstore@1.0-service.rc
@@ -0,0 +1,4 @@
+service configstore-hal-1-0 /system/bin/hw/android.hardware.configstore@1.0-service
+    class hal
+    user system
+    group system
diff --git a/configstore/1.0/default/service.cpp b/configstore/1.0/default/service.cpp
new file mode 100644
index 0000000..caec0ba
--- /dev/null
+++ b/configstore/1.0/default/service.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.configstore@1.0-service"
+
+#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <hidl/LegacySupport.h>
+
+using android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+
+int main() {
+    // TODO(b/34857894): tune the max thread count.
+    configureRpcThreadpool(10, true);
+    registerPassthroughServiceImplementation<ISurfaceFlingerConfigs>();
+    // other interface registration comes here
+    joinRpcThreadpool();
+    return 0;
+}
diff --git a/configstore/1.0/default/surfaceflinger.mk b/configstore/1.0/default/surfaceflinger.mk
new file mode 100644
index 0000000..42fa191
--- /dev/null
+++ b/configstore/1.0/default/surfaceflinger.mk
@@ -0,0 +1,6 @@
+
+LOCAL_SRC_FILES += SurfaceFlingerConfigs.cpp
+
+ifneq ($(VSYNC_EVENT_PHASE_OFFSET_NS),)
+    LOCAL_CFLAGS += -DVSYNC_EVENT_PHASE_OFFSET_NS=$(VSYNC_EVENT_PHASE_OFFSET_NS)
+endif
diff --git a/configstore/1.0/types.hal b/configstore/1.0/types.hal
new file mode 100644
index 0000000..49e9bef
--- /dev/null
+++ b/configstore/1.0/types.hal
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.configstore@1.0;
+
+struct OptionalBool {
+    bool specified;
+    bool value;
+};
+
+struct OptionalInt32 {
+    bool specified;
+    int32_t value;
+};
+
+struct OptionalUInt32 {
+    bool specified;
+    uint32_t value;
+};
+
+struct OptionalInt64 {
+    bool specified;
+    int64_t value;
+};
+
+struct OptionalUInt64 {
+    bool specified;
+    uint64_t value;
+};
+
+struct OptionalString {
+    bool specified;
+    string value;
+};
diff --git a/configstore/Android.bp b/configstore/Android.bp
new file mode 100644
index 0000000..bbb3e4b
--- /dev/null
+++ b/configstore/Android.bp
@@ -0,0 +1,4 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+    "1.0",
+]
diff --git a/drm/1.0/Android.bp b/drm/1.0/Android.bp
index d899114..3c9f22b 100644
--- a/drm/1.0/Android.bp
+++ b/drm/1.0/Android.bp
@@ -86,3 +86,302 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.drm.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "types.hal",
+        "ICryptoFactory.hal",
+        "ICryptoPlugin.hal",
+        "IDrmFactory.hal",
+        "IDrmPlugin.hal",
+        "IDrmPluginListener.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/types.vts.cpp",
+        "android/hardware/drm/1.0/CryptoFactory.vts.cpp",
+        "android/hardware/drm/1.0/CryptoPlugin.vts.cpp",
+        "android/hardware/drm/1.0/DrmFactory.vts.cpp",
+        "android/hardware/drm/1.0/DrmPlugin.vts.cpp",
+        "android/hardware/drm/1.0/DrmPluginListener.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "types.hal",
+        "ICryptoFactory.hal",
+        "ICryptoPlugin.hal",
+        "IDrmFactory.hal",
+        "IDrmPlugin.hal",
+        "IDrmPluginListener.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/types.vts.h",
+        "android/hardware/drm/1.0/CryptoFactory.vts.h",
+        "android/hardware/drm/1.0/CryptoPlugin.vts.h",
+        "android/hardware/drm/1.0/DrmFactory.vts.h",
+        "android/hardware/drm/1.0/DrmPlugin.vts.h",
+        "android/hardware/drm/1.0/DrmPluginListener.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.drm.vts.driver@1.0",
+    generated_sources: ["android.hardware.drm.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.drm.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.drm.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.drm@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-ICryptoFactory-vts.profiler_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "ICryptoFactory.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/CryptoFactory.vts.cpp",
+        "android/hardware/drm/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-ICryptoFactory-vts.profiler_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "ICryptoFactory.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/CryptoFactory.vts.h",
+        "android/hardware/drm/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.drm@1.0-ICryptoFactory-vts.profiler",
+    generated_sources: ["android.hardware.drm@1.0-ICryptoFactory-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.drm@1.0-ICryptoFactory-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.drm@1.0-ICryptoFactory-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.drm@1.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-ICryptoPlugin-vts.profiler_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "ICryptoPlugin.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/CryptoPlugin.vts.cpp",
+        "android/hardware/drm/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-ICryptoPlugin-vts.profiler_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "ICryptoPlugin.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/CryptoPlugin.vts.h",
+        "android/hardware/drm/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.drm@1.0-ICryptoPlugin-vts.profiler",
+    generated_sources: ["android.hardware.drm@1.0-ICryptoPlugin-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.drm@1.0-ICryptoPlugin-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.drm@1.0-ICryptoPlugin-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.drm@1.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-IDrmFactory-vts.profiler_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "IDrmFactory.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/DrmFactory.vts.cpp",
+        "android/hardware/drm/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-IDrmFactory-vts.profiler_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "IDrmFactory.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/DrmFactory.vts.h",
+        "android/hardware/drm/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.drm@1.0-IDrmFactory-vts.profiler",
+    generated_sources: ["android.hardware.drm@1.0-IDrmFactory-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.drm@1.0-IDrmFactory-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.drm@1.0-IDrmFactory-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.drm@1.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-IDrmPlugin-vts.profiler_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "IDrmPlugin.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/DrmPlugin.vts.cpp",
+        "android/hardware/drm/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-IDrmPlugin-vts.profiler_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "IDrmPlugin.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/DrmPlugin.vts.h",
+        "android/hardware/drm/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.drm@1.0-IDrmPlugin-vts.profiler",
+    generated_sources: ["android.hardware.drm@1.0-IDrmPlugin-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.drm@1.0-IDrmPlugin-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.drm@1.0-IDrmPlugin-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.drm@1.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-IDrmPluginListener-vts.profiler_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "IDrmPluginListener.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/DrmPluginListener.vts.cpp",
+        "android/hardware/drm/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.drm@1.0-IDrmPluginListener-vts.profiler_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/drm/1.0/ $(genDir)/android/hardware/drm/1.0/",
+    srcs: [
+        "IDrmPluginListener.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/drm/1.0/DrmPluginListener.vts.h",
+        "android/hardware/drm/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.drm@1.0-IDrmPluginListener-vts.profiler",
+    generated_sources: ["android.hardware.drm@1.0-IDrmPluginListener-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.drm@1.0-IDrmPluginListener-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.drm@1.0-IDrmPluginListener-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.drm@1.0",
+    ],
+}
diff --git a/gatekeeper/1.0/Android.bp b/gatekeeper/1.0/Android.bp
index 8ef33ab..d4852ff 100644
--- a/gatekeeper/1.0/Android.bp
+++ b/gatekeeper/1.0/Android.bp
@@ -54,3 +54,106 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.gatekeeper.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.gatekeeper@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/gatekeeper/1.0/ $(genDir)/android/hardware/gatekeeper/1.0/",
+    srcs: [
+        "types.hal",
+        "IGatekeeper.hal",
+    ],
+    out: [
+        "android/hardware/gatekeeper/1.0/types.vts.cpp",
+        "android/hardware/gatekeeper/1.0/Gatekeeper.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.gatekeeper.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.gatekeeper@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/gatekeeper/1.0/ $(genDir)/android/hardware/gatekeeper/1.0/",
+    srcs: [
+        "types.hal",
+        "IGatekeeper.hal",
+    ],
+    out: [
+        "android/hardware/gatekeeper/1.0/types.vts.h",
+        "android/hardware/gatekeeper/1.0/Gatekeeper.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.gatekeeper.vts.driver@1.0",
+    generated_sources: ["android.hardware.gatekeeper.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.gatekeeper.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.gatekeeper.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.gatekeeper@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.gatekeeper@1.0-IGatekeeper-vts.profiler_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.gatekeeper@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/gatekeeper/1.0/ $(genDir)/android/hardware/gatekeeper/1.0/",
+    srcs: [
+        "IGatekeeper.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/gatekeeper/1.0/Gatekeeper.vts.cpp",
+        "android/hardware/gatekeeper/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.gatekeeper@1.0-IGatekeeper-vts.profiler_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.gatekeeper@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/gatekeeper/1.0/ $(genDir)/android/hardware/gatekeeper/1.0/",
+    srcs: [
+        "IGatekeeper.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/gatekeeper/1.0/Gatekeeper.vts.h",
+        "android/hardware/gatekeeper/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.gatekeeper@1.0-IGatekeeper-vts.profiler",
+    generated_sources: ["android.hardware.gatekeeper@1.0-IGatekeeper-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.gatekeeper@1.0-IGatekeeper-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.gatekeeper@1.0-IGatekeeper-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.gatekeeper@1.0",
+    ],
+}
diff --git a/gatekeeper/1.0/vts/functional/Android.bp b/gatekeeper/1.0/vts/functional/Android.bp
index 9c72b81..e79e40e 100644
--- a/gatekeeper/1.0/vts/functional/Android.bp
+++ b/gatekeeper/1.0/vts/functional/Android.bp
@@ -31,7 +31,11 @@
     ],
     static_libs: ["libgtest"],
     cflags: [
+        "--coverage",
         "-O0",
         "-g",
     ],
+    ldflags: [
+        "--coverage"
+    ]
 }
diff --git a/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/__init__.py b/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/__init__.py
+++ /dev/null
diff --git a/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/__init__.py b/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/__init__.py
+++ /dev/null
diff --git a/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/target/AndroidTest.xml b/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/target/AndroidTest.xml
index 9256823..2e258ca 100644
--- a/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/target/AndroidTest.xml
+++ b/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/target/AndroidTest.xml
@@ -25,6 +25,6 @@
             _64bit::DATA/nativetest64/gatekeeper_hidl_hal_test/gatekeeper_hidl_hal_test,
             "/>
         <option name="binary-test-type" value="gtest" />
-        <option name="test-timeout" value="1m" />
+        <option name="test-timeout" value="5m" />
     </test>
 </configuration>
diff --git a/graphics/Android.bp b/graphics/Android.bp
index 6d55dd1..eaa47ae 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -6,6 +6,7 @@
     "common/1.0",
     "composer/2.1",
     "composer/2.1/default",
+    "composer/2.1/vts/functional",
     "mapper/2.0",
     "mapper/2.0/default",
     "mapper/2.0/vts/functional",
diff --git a/graphics/composer/2.1/Android.mk b/graphics/composer/2.1/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/graphics/composer/2.1/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/graphics/composer/2.1/IComposer.hal b/graphics/composer/2.1/IComposer.hal
index 771fc7d..553a537 100644
--- a/graphics/composer/2.1/IComposer.hal
+++ b/graphics/composer/2.1/IComposer.hal
@@ -53,6 +53,9 @@
      *
      * @return capabilities is a list of supported capabilities.
      */
+    @entry
+    @exit
+    @callflow(next="*")
     getCapabilities() generates (vec<Capability> capabilities);
 
     /*
@@ -61,6 +64,9 @@
      *
      * @return debugInfo is a string of debug information.
      */
+    @entry
+    @exit
+    @callflow(next="*")
     dumpDebugInfo() generates (string debugInfo);
 
     /*
@@ -73,5 +79,7 @@
      *         NO_RESOURCES when no more client can be created currently.
      * @return client is the newly created client.
      */
+    @entry
+    @callflow(next="*")
     createClient() generates (Error error, IComposerClient client);
 };
diff --git a/graphics/composer/2.1/IComposerCallback.hal b/graphics/composer/2.1/IComposerCallback.hal
index a8ca168..541d7eb 100644
--- a/graphics/composer/2.1/IComposerCallback.hal
+++ b/graphics/composer/2.1/IComposerCallback.hal
@@ -44,6 +44,7 @@
      * @param connected indicates whether the display is connected or
      *        disconnected.
      */
+    @callflow(next="*")
     onHotplug(Display display, Connection connected);
 
     /*
@@ -57,6 +58,7 @@
      *
      * @param display is the display to refresh.
      */
+    @callflow(next="*")
     oneway onRefresh(Display display);
 
     /*
@@ -68,5 +70,6 @@
      * @param timestamp is the CLOCK_MONOTONIC time at which the vsync event
      *        occurred, in nanoseconds.
      */
+    @callflow(next="*")
     oneway onVsync(Display display, int64_t timestamp);
 };
diff --git a/graphics/composer/2.1/IComposerClient.hal b/graphics/composer/2.1/IComposerClient.hal
index b0bd837..107ac5e 100644
--- a/graphics/composer/2.1/IComposerClient.hal
+++ b/graphics/composer/2.1/IComposerClient.hal
@@ -240,6 +240,8 @@
      *
      * @param callback is the IComposerCallback object.
      */
+    @entry
+    @callflow(next="*")
     registerCallback(IComposerCallback callback);
 
     /*
@@ -250,6 +252,7 @@
      *
      * @return count is the maximum number of virtual displays supported.
      */
+    @callflow(next="*")
     getMaxVirtualDisplayCount() generates (uint32_t count);
 
     /*
@@ -274,6 +277,7 @@
      * @return display is the newly-created virtual display.
      * @return format is the format of the buffer the device will produce.
      */
+    @callflow(next="*")
     createVirtualDisplay(uint32_t width,
                          uint32_t height,
                          PixelFormat formatHint,
@@ -293,6 +297,7 @@
      *         BAD_PARAMETER when the display handle which was passed in does
      *                       not refer to a virtual display.
      */
+    @callflow(next="*")
     destroyVirtualDisplay(Display display) generates (Error error);
 
     /*
@@ -306,6 +311,7 @@
      *                      time.
      * @return layer is the handle of the new layer.
      */
+    @callflow(next="*")
     createLayer(Display display,
                 uint32_t bufferSlotCount)
      generates (Error error,
@@ -320,6 +326,7 @@
      *         BAD_DISPLAY when an invalid display handle was passed in.
      *         BAD_LAYER when an invalid layer handle was passed in.
      */
+    @callflow(next="*")
     destroyLayer(Display display, Layer layer) generates (Error error);
 
     /*
@@ -336,6 +343,7 @@
      *         BAD_CONFIG when no configuration is currently active.
      * @return config is the currently active display configuration.
      */
+    @callflow(next="*")
     getActiveConfig(Display display) generates (Error error, Config config);
 
     /*
@@ -357,6 +365,7 @@
      *         BAD_DISPLAY when an invalid display handle was passed in.
      *         UNSUPPORTED when the given configuration is not supported.
      */
+    @callflow(next="*")
     getClientTargetSupport(Display display,
                            uint32_t width,
                            uint32_t height,
@@ -374,6 +383,7 @@
      *         BAD_DISPLAY when an invalid display handle was passed in.
      * @return modes is an array of color modes.
      */
+    @callflow(next="*")
     getColorModes(Display display)
        generates (Error error,
                   vec<ColorMode> modes);
@@ -393,6 +403,7 @@
      *         UNSUPPORTED when attribute cannot be queried for the config.
      * @return value is the value of the attribute.
      */
+    @callflow(next="*")
     getDisplayAttribute(Display display,
                         Config config,
                         Attribute attribute)
@@ -408,6 +419,7 @@
      *         BAD_DISPLAY when an invalid display handle was passed in.
      * @return configs is an array of configuration handles.
      */
+    @callflow(next="*")
     getDisplayConfigs(Display display)
            generates (Error error,
                       vec<Config> configs);
@@ -419,6 +431,7 @@
      *         BAD_DISPLAY when an invalid display handle was passed in.
      * @return name is the name of the display.
      */
+    @callflow(next="*")
     getDisplayName(Display display) generates (Error error, string name);
 
     /*
@@ -429,6 +442,7 @@
      *         BAD_DISPLAY when an invalid display handle was passed in.
      * @return type is the type of the display.
      */
+    @callflow(next="*")
     getDisplayType(Display display) generates (Error error, DisplayType type);
 
     /*
@@ -443,6 +457,7 @@
      *         BAD_DISPLAY when an invalid display handle was passed in.
      * @return support is true only when the display supports doze modes.
      */
+    @callflow(next="*")
     getDozeSupport(Display display) generates (Error error, bool support);
 
     /*
@@ -463,6 +478,7 @@
      * @return minLuminance is the desired content minimum luminance for this
      *         display in cd/m^2.
      */
+    @callflow(next="*")
     getHdrCapabilities(Display display)
             generates (Error error,
                        vec<Hdr> types,
@@ -479,6 +495,7 @@
      *         BAD_DISPLAY when an invalid display handle was passed in.
      *         NO_RESOURCES when unable to reserve the slots.
      */
+    @callflow(next="*")
     setClientTargetSlotCount(Display display,
                              uint32_t clientTargetSlotCount)
                   generates (Error error);
@@ -495,6 +512,7 @@
      *         BAD_CONFIG when the configuration handle passed in is not valid
      *                    for this display.
      */
+    @callflow(next="*")
     setActiveConfig(Display display, Config config) generates (Error error);
 
     /*
@@ -513,6 +531,7 @@
      *         BAD_PARAMETER when mode is not a valid color mode.
      *         UNSUPPORTED when mode is not supported on this display.
      */
+    @callflow(next="*")
     setColorMode(Display display, ColorMode mode) generates (Error error);
 
     /*
@@ -531,6 +550,7 @@
      *         BAD_PARAMETER when mode was not a valid power mode.
      *         UNSUPPORTED when mode is not supported on this display.
      */
+    @callflow(next="*")
     setPowerMode(Display display, PowerMode mode) generates (Error error);
 
     /*
@@ -545,6 +565,7 @@
      *         BAD_DISPLAY when an invalid display handle was passed in.
      *         BAD_PARAMETER when enabled was an invalid value.
      */
+    @callflow(next="*")
     setVsyncEnabled(Display display, Vsync enabled) generates (Error error);
 
     /*
@@ -554,6 +575,7 @@
      * @return error is NONE upon success. Otherwise,
      *         NO_RESOURCES when failed to set the queue temporarily.
      */
+    @callflow(next="*")
     setInputCommandQueue(fmq_sync<uint32_t> descriptor)
               generates (Error error);
 
@@ -566,6 +588,7 @@
      *         NO_RESOURCES when failed to get the queue temporarily.
      * @return descriptor is the descriptor of the output command queue.
      */
+    @callflow(next="*")
     getOutputCommandQueue()
               generates (Error error,
                          fmq_sync<uint32_t> descriptor);
@@ -589,6 +612,7 @@
      * @param outHandles is an array of handles referenced by the output
      *        commands.
      */
+    @callflow(next="*")
     executeCommands(uint32_t inLength,
                     vec<handle> inHandles)
          generates (Error error,
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index a366fa2..46cd0c4 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -2,7 +2,6 @@
     name: "libhwcomposer-client",
     export_include_dirs: ["."],
     srcs: ["ComposerClient.cpp"],
-    cppflags: ["-DBINDERIZED"],
     shared_libs: [
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.composer@2.1",
@@ -22,7 +21,8 @@
 cc_library_shared {
     name: "android.hardware.graphics.composer@2.1-impl",
     relative_install_path: "hw",
-    srcs: ["Hwc.cpp", "ComposerClient.cpp"],
+    srcs: ["Hwc.cpp"],
+    static_libs: ["libhwcomposer-client"],
     shared_libs: [
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.composer@2.1",
@@ -42,13 +42,9 @@
 cc_binary {
     name: "android.hardware.graphics.composer@2.1-service",
     relative_install_path: "hw",
-    srcs: ["service.cpp", "Hwc.cpp"],
-    cppflags: ["-DBINDERIZED"],
+    srcs: ["service.cpp"],
     init_rc: ["android.hardware.graphics.composer@2.1-service.rc"],
-
-    static_libs: [
-        "libhwcomposer-client",
-    ],
+    static_libs: ["libhwcomposer-client"],
     shared_libs: [
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.composer@2.1",
diff --git a/graphics/composer/2.1/default/ComposerClient.cpp b/graphics/composer/2.1/default/ComposerClient.cpp
index 49415ee..7a2cb25 100644
--- a/graphics/composer/2.1/default/ComposerClient.cpp
+++ b/graphics/composer/2.1/default/ComposerClient.cpp
@@ -99,7 +99,6 @@
 
     // Some existing gralloc drivers do not support retaining more than once,
     // when we are in passthrough mode.
-#ifdef BINDERIZED
     bool openGralloc()
     {
         const hw_module_t* module = nullptr;
@@ -188,12 +187,6 @@
 
     // gralloc0
     const gralloc_module_t* mModule;
-#else
-    bool openGralloc() { return true; }
-    void closeGralloc() {}
-    buffer_handle_t cloneBuffer(buffer_handle_t handle) { return handle; }
-    void releaseBuffer(buffer_handle_t) {}
-#endif
 };
 
 HandleImporter sHandleImporter;
diff --git a/graphics/composer/2.1/default/service.cpp b/graphics/composer/2.1/default/service.cpp
index c2a2b19..a31decd 100644
--- a/graphics/composer/2.1/default/service.cpp
+++ b/graphics/composer/2.1/default/service.cpp
@@ -14,41 +14,20 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "HWComposerService"
+#define LOG_TAG "android.hardware.graphics.composer@2.1-service"
+
+#include <android/hardware/graphics/composer/2.1/IComposer.h>
 
 #include <binder/ProcessState.h>
-#include <hidl/HidlTransportSupport.h>
-#include <utils/StrongPointer.h>
-#include "Hwc.h"
+#include <hidl/LegacySupport.h>
 
-using android::hardware::configureRpcThreadpool;
-using android::hardware::joinRpcThreadpool;
-using android::sp;
 using android::hardware::graphics::composer::V2_1::IComposer;
-using android::hardware::graphics::composer::V2_1::implementation::HIDL_FETCH_IComposer;
+using android::hardware::defaultPassthroughServiceImplementation;
 
-int main()
-{
-    const char instance[] = "hwcomposer";
-
-    ALOGI("Service is starting.");
-
-    configureRpcThreadpool(1, true /* callerWillJoin */);
-    sp<IComposer> service = HIDL_FETCH_IComposer(instance);
-    if (service == nullptr) {
-        ALOGI("getService returned NULL");
-        return -1;
-    }
-
-    LOG_FATAL_IF(service->isRemote(), "Service is REMOTE!");
-
-    service->registerAsService(instance);
-
+int main() {
     // the conventional HAL might start binder services
     android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
     android::ProcessState::self()->startThreadPool();
 
-    joinRpcThreadpool();
-
-    return 0;
+    return defaultPassthroughServiceImplementation<IComposer>("hwcomposer");
 }
diff --git a/graphics/composer/2.1/vts/Android.mk b/graphics/composer/2.1/vts/Android.mk
new file mode 100644
index 0000000..b9ddc6e
--- /dev/null
+++ b/graphics/composer/2.1/vts/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(LOCAL_PATH)/functional/vts/testcases/hal/graphics/composer/hidl/target/Android.mk
diff --git a/graphics/composer/2.1/vts/Composer.vts b/graphics/composer/2.1/vts/Composer.vts
new file mode 100644
index 0000000..ee5c650
--- /dev/null
+++ b/graphics/composer/2.1/vts/Composer.vts
@@ -0,0 +1,87 @@
+component_class: HAL_HIDL
+component_type_version: 2.1
+component_name: "IComposer"
+
+package: "android.hardware.graphics.composer"
+
+import: "android.hardware.graphics.composer@2.1::IComposerClient"
+import: "android.hardware.graphics.composer@2.1::types"
+
+interface: {
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposer::Capability"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "INVALID"
+            scalar_value: {
+                int32_t: 0
+            }
+            enumerator: "SIDEBAND_STREAM"
+            scalar_value: {
+                int32_t: 1
+            }
+            enumerator: "SKIP_CLIENT_COLOR_TRANSFORM"
+            scalar_value: {
+                int32_t: 2
+            }
+        }
+    }
+
+    api: {
+        name: "getCapabilities"
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_ENUM
+                predefined_type: "::android::hardware::graphics::composer::V2_1::IComposer::Capability"
+            }
+        }
+        callflow: {
+            entry: true
+        }
+        callflow: {
+            exit: true
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "dumpDebugInfo"
+        return_type_hidl: {
+            type: TYPE_STRING
+        }
+        callflow: {
+            entry: true
+        }
+        callflow: {
+            exit: true
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "createClient"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_HIDL_INTERFACE
+            predefined_type: "IComposerClient"
+            is_callback: false
+        }
+        callflow: {
+            entry: true
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+}
diff --git a/graphics/composer/2.1/vts/ComposerCallback.vts b/graphics/composer/2.1/vts/ComposerCallback.vts
new file mode 100644
index 0000000..a5a2aa9
--- /dev/null
+++ b/graphics/composer/2.1/vts/ComposerCallback.vts
@@ -0,0 +1,72 @@
+component_class: HAL_HIDL
+component_type_version: 2.1
+component_name: "IComposerCallback"
+
+package: "android.hardware.graphics.composer"
+
+import: "android.hardware.graphics.composer@2.1::types"
+
+interface: {
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerCallback::Connection"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "INVALID"
+            scalar_value: {
+                int32_t: 0
+            }
+            enumerator: "CONNECTED"
+            scalar_value: {
+                int32_t: 1
+            }
+            enumerator: "DISCONNECTED"
+            scalar_value: {
+                int32_t: 2
+            }
+        }
+    }
+
+    api: {
+        name: "onHotplug"
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::IComposerCallback::Connection"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "onRefresh"
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "onVsync"
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+}
diff --git a/graphics/composer/2.1/vts/ComposerClient.vts b/graphics/composer/2.1/vts/ComposerClient.vts
new file mode 100644
index 0000000..db6b1ff
--- /dev/null
+++ b/graphics/composer/2.1/vts/ComposerClient.vts
@@ -0,0 +1,906 @@
+component_class: HAL_HIDL
+component_type_version: 2.1
+component_name: "IComposerClient"
+
+package: "android.hardware.graphics.composer"
+
+import: "android.hardware.graphics.common@1.0::types"
+import: "android.hardware.graphics.composer@2.1::IComposerCallback"
+import: "android.hardware.graphics.composer@2.1::types"
+
+interface: {
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::Attribute"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "INVALID"
+            scalar_value: {
+                int32_t: 0
+            }
+            enumerator: "WIDTH"
+            scalar_value: {
+                int32_t: 1
+            }
+            enumerator: "HEIGHT"
+            scalar_value: {
+                int32_t: 2
+            }
+            enumerator: "VSYNC_PERIOD"
+            scalar_value: {
+                int32_t: 3
+            }
+            enumerator: "DPI_X"
+            scalar_value: {
+                int32_t: 4
+            }
+            enumerator: "DPI_Y"
+            scalar_value: {
+                int32_t: 5
+            }
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::DisplayRequest"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "uint32_t"
+
+            enumerator: "FLIP_CLIENT_TARGET"
+            scalar_value: {
+                uint32_t: 1
+            }
+            enumerator: "WRITE_CLIENT_TARGET_TO_OUTPUT"
+            scalar_value: {
+                uint32_t: 2
+            }
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::LayerRequest"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "uint32_t"
+
+            enumerator: "CLEAR_CLIENT_TARGET"
+            scalar_value: {
+                uint32_t: 1
+            }
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::PowerMode"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "OFF"
+            scalar_value: {
+                int32_t: 0
+            }
+            enumerator: "DOZE"
+            scalar_value: {
+                int32_t: 1
+            }
+            enumerator: "DOZE_SUSPEND"
+            scalar_value: {
+                int32_t: 3
+            }
+            enumerator: "ON"
+            scalar_value: {
+                int32_t: 2
+            }
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::Vsync"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "INVALID"
+            scalar_value: {
+                int32_t: 0
+            }
+            enumerator: "ENABLE"
+            scalar_value: {
+                int32_t: 1
+            }
+            enumerator: "DISABLE"
+            scalar_value: {
+                int32_t: 2
+            }
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "INVALID"
+            scalar_value: {
+                int32_t: 0
+            }
+            enumerator: "NONE"
+            scalar_value: {
+                int32_t: 1
+            }
+            enumerator: "PREMULTIPLIED"
+            scalar_value: {
+                int32_t: 2
+            }
+            enumerator: "COVERAGE"
+            scalar_value: {
+                int32_t: 3
+            }
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::Composition"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "INVALID"
+            scalar_value: {
+                int32_t: 0
+            }
+            enumerator: "CLIENT"
+            scalar_value: {
+                int32_t: 1
+            }
+            enumerator: "DEVICE"
+            scalar_value: {
+                int32_t: 2
+            }
+            enumerator: "SOLID_COLOR"
+            scalar_value: {
+                int32_t: 3
+            }
+            enumerator: "CURSOR"
+            scalar_value: {
+                int32_t: 4
+            }
+            enumerator: "SIDEBAND"
+            scalar_value: {
+                int32_t: 5
+            }
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::DisplayType"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "INVALID"
+            scalar_value: {
+                int32_t: 0
+            }
+            enumerator: "PHYSICAL"
+            scalar_value: {
+                int32_t: 1
+            }
+            enumerator: "VIRTUAL"
+            scalar_value: {
+                int32_t: 2
+            }
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::HandleIndex"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "EMPTY"
+            scalar_value: {
+                int32_t: -1
+            }
+            enumerator: "CACHED"
+            scalar_value: {
+                int32_t: -2
+            }
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::Rect"
+        type: TYPE_STRUCT
+        struct_value: {
+            name: "left"
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+        struct_value: {
+            name: "top"
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+        struct_value: {
+            name: "right"
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+        struct_value: {
+            name: "bottom"
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::FRect"
+        type: TYPE_STRUCT
+        struct_value: {
+            name: "left"
+            type: TYPE_SCALAR
+            scalar_type: "float_t"
+        }
+        struct_value: {
+            name: "top"
+            type: TYPE_SCALAR
+            scalar_type: "float_t"
+        }
+        struct_value: {
+            name: "right"
+            type: TYPE_SCALAR
+            scalar_type: "float_t"
+        }
+        struct_value: {
+            name: "bottom"
+            type: TYPE_SCALAR
+            scalar_type: "float_t"
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::Color"
+        type: TYPE_STRUCT
+        struct_value: {
+            name: "r"
+            type: TYPE_SCALAR
+            scalar_type: "uint8_t"
+        }
+        struct_value: {
+            name: "g"
+            type: TYPE_SCALAR
+            scalar_type: "uint8_t"
+        }
+        struct_value: {
+            name: "b"
+            type: TYPE_SCALAR
+            scalar_type: "uint8_t"
+        }
+        struct_value: {
+            name: "a"
+            type: TYPE_SCALAR
+            scalar_type: "uint8_t"
+        }
+    }
+
+    attribute: {
+        name: "::android::hardware::graphics::composer::V2_1::IComposerClient::Command"
+        type: TYPE_ENUM
+        enum_value: {
+            scalar_type: "int32_t"
+
+            enumerator: "LENGTH_MASK"
+            scalar_value: {
+                int32_t: 65535
+            }
+            enumerator: "OPCODE_SHIFT"
+            scalar_value: {
+                int32_t: 16
+            }
+            enumerator: "OPCODE_MASK"
+            scalar_value: {
+                int32_t: -65536
+            }
+            enumerator: "SELECT_DISPLAY"
+            scalar_value: {
+                int32_t: 0
+            }
+            enumerator: "SELECT_LAYER"
+            scalar_value: {
+                int32_t: 65536
+            }
+            enumerator: "SET_ERROR"
+            scalar_value: {
+                int32_t: 16777216
+            }
+            enumerator: "SET_CHANGED_COMPOSITION_TYPES"
+            scalar_value: {
+                int32_t: 16842752
+            }
+            enumerator: "SET_DISPLAY_REQUESTS"
+            scalar_value: {
+                int32_t: 16908288
+            }
+            enumerator: "SET_PRESENT_FENCE"
+            scalar_value: {
+                int32_t: 16973824
+            }
+            enumerator: "SET_RELEASE_FENCES"
+            scalar_value: {
+                int32_t: 17039360
+            }
+            enumerator: "SET_COLOR_TRANSFORM"
+            scalar_value: {
+                int32_t: 33554432
+            }
+            enumerator: "SET_CLIENT_TARGET"
+            scalar_value: {
+                int32_t: 33619968
+            }
+            enumerator: "SET_OUTPUT_BUFFER"
+            scalar_value: {
+                int32_t: 33685504
+            }
+            enumerator: "VALIDATE_DISPLAY"
+            scalar_value: {
+                int32_t: 33751040
+            }
+            enumerator: "ACCEPT_DISPLAY_CHANGES"
+            scalar_value: {
+                int32_t: 33816576
+            }
+            enumerator: "PRESENT_DISPLAY"
+            scalar_value: {
+                int32_t: 33882112
+            }
+            enumerator: "SET_LAYER_CURSOR_POSITION"
+            scalar_value: {
+                int32_t: 50331648
+            }
+            enumerator: "SET_LAYER_BUFFER"
+            scalar_value: {
+                int32_t: 50397184
+            }
+            enumerator: "SET_LAYER_SURFACE_DAMAGE"
+            scalar_value: {
+                int32_t: 50462720
+            }
+            enumerator: "SET_LAYER_BLEND_MODE"
+            scalar_value: {
+                int32_t: 67108864
+            }
+            enumerator: "SET_LAYER_COLOR"
+            scalar_value: {
+                int32_t: 67174400
+            }
+            enumerator: "SET_LAYER_COMPOSITION_TYPE"
+            scalar_value: {
+                int32_t: 67239936
+            }
+            enumerator: "SET_LAYER_DATASPACE"
+            scalar_value: {
+                int32_t: 67305472
+            }
+            enumerator: "SET_LAYER_DISPLAY_FRAME"
+            scalar_value: {
+                int32_t: 67371008
+            }
+            enumerator: "SET_LAYER_PLANE_ALPHA"
+            scalar_value: {
+                int32_t: 67436544
+            }
+            enumerator: "SET_LAYER_SIDEBAND_STREAM"
+            scalar_value: {
+                int32_t: 67502080
+            }
+            enumerator: "SET_LAYER_SOURCE_CROP"
+            scalar_value: {
+                int32_t: 67567616
+            }
+            enumerator: "SET_LAYER_TRANSFORM"
+            scalar_value: {
+                int32_t: 67633152
+            }
+            enumerator: "SET_LAYER_VISIBLE_REGION"
+            scalar_value: {
+                int32_t: 67698688
+            }
+            enumerator: "SET_LAYER_Z_ORDER"
+            scalar_value: {
+                int32_t: 67764224
+            }
+        }
+    }
+
+    api: {
+        name: "registerCallback"
+        arg: {
+            type: TYPE_HIDL_CALLBACK
+            predefined_type: "IComposerCallback"
+            is_callback: true
+        }
+        callflow: {
+            entry: true
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getMaxVirtualDisplayCount"
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "createVirtualDisplay"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::common::V1_0::PixelFormat"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        arg: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::common::V1_0::PixelFormat"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "destroyVirtualDisplay"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "createLayer"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "destroyLayer"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getActiveConfig"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getClientTargetSupport"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        arg: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::common::V1_0::PixelFormat"
+        }
+        arg: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::common::V1_0::Dataspace"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getColorModes"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_ENUM
+                predefined_type: "::android::hardware::graphics::common::V1_0::ColorMode"
+            }
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getDisplayAttribute"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        arg: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::IComposerClient::Attribute"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getDisplayConfigs"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_SCALAR
+                scalar_type: "uint32_t"
+            }
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getDisplayName"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_STRING
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getDisplayType"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::IComposerClient::DisplayType"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getDozeSupport"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "bool_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getHdrCapabilities"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_ENUM
+                predefined_type: "::android::hardware::graphics::common::V1_0::Hdr"
+            }
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "float_t"
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "float_t"
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "float_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "setClientTargetSlotCount"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "setActiveConfig"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "setColorMode"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::common::V1_0::ColorMode"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "setPowerMode"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::IComposerClient::PowerMode"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "setVsyncEnabled"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint64_t"
+        }
+        arg: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::IComposerClient::Vsync"
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "setInputCommandQueue"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        arg: {
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "getOutputCommandQueue"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+    api: {
+        name: "executeCommands"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::graphics::composer::V2_1::Error"
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "bool_t"
+        }
+        return_type_hidl: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_HANDLE
+            }
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+        arg: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_HANDLE
+            }
+        }
+        callflow: {
+            next: "*"
+        }
+    }
+
+}
diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp
new file mode 100644
index 0000000..c3f7636
--- /dev/null
+++ b/graphics/composer/2.1/vts/functional/Android.bp
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "graphics_composer_hidl_hal_test",
+    gtest: true,
+    srcs: ["graphics_composer_hidl_hal_test.cpp"],
+    shared_libs: [
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.composer@2.1",
+        "android.hardware.graphics.mapper@2.0",
+        "libbase",
+        "libcutils",
+        "libfmq",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libnativehelper",
+        "libsync",
+        "libutils",
+    ],
+    static_libs: ["libgtest", "libhwcomposer-command-buffer"],
+    cflags: [
+        "--coverage",
+        "-O0",
+        "-g",
+    ],
+    ldflags: [
+        "--coverage",
+    ],
+}
diff --git a/graphics/composer/2.1/vts/functional/graphics_composer_hidl_hal_test.cpp b/graphics/composer/2.1/vts/functional/graphics_composer_hidl_hal_test.cpp
new file mode 100644
index 0000000..e3e35bb
--- /dev/null
+++ b/graphics/composer/2.1/vts/functional/graphics_composer_hidl_hal_test.cpp
@@ -0,0 +1,1131 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "graphics_composer_hidl_hal_test"
+
+#include <IComposerCommandBuffer.h>
+#include <android-base/logging.h>
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/composer/2.1/IComposer.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+#include <gtest/gtest.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <array>
+#include <memory>
+#include <mutex>
+#include <unordered_set>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace tests {
+namespace {
+
+using android::hardware::graphics::allocator::V2_0::Buffer;
+using android::hardware::graphics::allocator::V2_0::BufferDescriptor;
+using android::hardware::graphics::allocator::V2_0::ConsumerUsage;
+using android::hardware::graphics::allocator::V2_0::IAllocator;
+using android::hardware::graphics::allocator::V2_0::IAllocatorClient;
+using android::hardware::graphics::allocator::V2_0::ProducerUsage;
+using android::hardware::graphics::common::V1_0::ColorMode;
+using android::hardware::graphics::common::V1_0::ColorTransform;
+using android::hardware::graphics::common::V1_0::Dataspace;
+using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::hardware::graphics::common::V1_0::Transform;
+using android::hardware::graphics::mapper::V2_0::IMapper;
+using GrallocError = android::hardware::graphics::allocator::V2_0::Error;
+
+// IComposerCallback to be installed with IComposerClient::registerCallback.
+class GraphicsComposerCallback : public IComposerCallback {
+ public:
+  void setVsyncAllowed(bool allowed) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    mVsyncAllowed = allowed;
+  }
+
+  std::vector<Display> getDisplays() const {
+    std::lock_guard<std::mutex> lock(mMutex);
+    return std::vector<Display>(mDisplays.begin(), mDisplays.end());
+  }
+
+  int getInvalidHotplugCount() const {
+    std::lock_guard<std::mutex> lock(mMutex);
+    return mInvalidHotplugCount;
+  }
+
+  int getInvalidRefreshCount() const {
+    std::lock_guard<std::mutex> lock(mMutex);
+    return mInvalidRefreshCount;
+  }
+
+  int getInvalidVsyncCount() const {
+    std::lock_guard<std::mutex> lock(mMutex);
+    return mInvalidVsyncCount;
+  }
+
+ private:
+  Return<void> onHotplug(Display display, Connection connection) override {
+    std::lock_guard<std::mutex> lock(mMutex);
+
+    if (connection == Connection::CONNECTED) {
+      if (!mDisplays.insert(display).second) {
+        mInvalidHotplugCount++;
+      }
+    } else if (connection == Connection::DISCONNECTED) {
+      if (!mDisplays.erase(display)) {
+        mInvalidHotplugCount++;
+      }
+    }
+
+    return Void();
+  }
+
+  Return<void> onRefresh(Display display) override {
+    std::lock_guard<std::mutex> lock(mMutex);
+
+    if (mDisplays.count(display) == 0) {
+      mInvalidRefreshCount++;
+    }
+
+    return Void();
+  }
+
+  Return<void> onVsync(Display display, int64_t) override {
+    std::lock_guard<std::mutex> lock(mMutex);
+
+    if (!mVsyncAllowed || mDisplays.count(display) == 0) {
+      mInvalidVsyncCount++;
+    }
+
+    return Void();
+  }
+
+  mutable std::mutex mMutex;
+  // the set of all currently connected displays
+  std::unordered_set<Display> mDisplays;
+  // true only when vsync is enabled
+  bool mVsyncAllowed = false;
+
+  // track invalid callbacks
+  int mInvalidHotplugCount = 0;
+  int mInvalidRefreshCount = 0;
+  int mInvalidVsyncCount = 0;
+};
+
+class GraphicsComposerHidlTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    mComposer = IComposer::getService("hwcomposer");
+    ASSERT_NE(nullptr, mComposer.get());
+
+    mComposerClient = createClient();
+    ASSERT_NE(nullptr, mComposerClient.get());
+
+    initCapabilities();
+
+    mComposerCallback = new GraphicsComposerCallback;
+    mComposerClient->registerCallback(mComposerCallback);
+
+    // assume the first display is primary and is never removed
+    mPrimaryDisplay = waitForFirstDisplay();
+  }
+
+  void TearDown() override {
+    if (mComposerCallback != nullptr) {
+      EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+      EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+      EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+    }
+  }
+
+  /**
+   * Initialize the set of supported capabilities.
+   */
+  void initCapabilities() {
+    mComposer->getCapabilities([this](const auto& capabilities) {
+      std::vector<IComposer::Capability> caps = capabilities;
+      mCapabilities.insert(caps.cbegin(), caps.cend());
+    });
+  }
+
+  /**
+   * Test whether a capability is supported.
+   */
+  bool hasCapability(IComposer::Capability capability) const {
+    return (mCapabilities.count(capability) > 0);
+  }
+
+  IComposerClient::DisplayType getDisplayType(Display display) {
+    IComposerClient::DisplayType type = IComposerClient::DisplayType::INVALID;
+    mComposerClient->getDisplayType(
+        display, [&](const auto& tmpError, const auto& tmpType) {
+          ASSERT_EQ(Error::NONE, tmpError);
+          type = tmpType;
+        });
+    return type;
+  }
+
+  Error createVirtualDisplay(Display* outDisplay) {
+    auto ret_count = mComposerClient->getMaxVirtualDisplayCount();
+    if (ret_count == 0) {
+      return Error::UNSUPPORTED;
+    }
+
+    Error err = Error::NO_RESOURCES;
+    Display display;
+    mComposerClient->createVirtualDisplay(
+        64, 64, PixelFormat::IMPLEMENTATION_DEFINED, kBufferSlotCount,
+        [&](const auto& tmpError, const auto& tmpDisplay, const auto&) {
+          err = tmpError;
+          display = tmpDisplay;
+        });
+
+    *outDisplay = display;
+    return err;
+  }
+
+  void destroyVirtualDisplay(Display display) {
+    auto ret = mComposerClient->destroyVirtualDisplay(display);
+    ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+  }
+
+  Error createLayer(Layer* outLayer) {
+    Error err = Error::NO_RESOURCES;
+    Layer layer;
+    mComposerClient->createLayer(
+        mPrimaryDisplay, kBufferSlotCount,
+        [&](const auto& tmpError, const auto& tmpLayer) {
+          err = tmpError;
+          layer = tmpLayer;
+        });
+
+    *outLayer = layer;
+    return err;
+  }
+
+  void destroyLayer(Layer layer) {
+    auto ret = mComposerClient->destroyLayer(mPrimaryDisplay, layer);
+    ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+  }
+
+  int32_t getDisplayAttribute(Config config,
+                              IComposerClient::Attribute attribute) {
+    int32_t value = -1;
+    mComposerClient->getDisplayAttribute(
+        mPrimaryDisplay, config, attribute,
+        [&](const auto& tmpError, const auto& tmpValue) {
+          ASSERT_EQ(Error::NONE, tmpError);
+          value = tmpValue;
+        });
+    return value;
+  }
+
+  std::vector<Config> getDisplayConfigs() {
+    std::vector<Config> configs;
+    mComposerClient->getDisplayConfigs(
+        mPrimaryDisplay, [&](const auto& tmpError, const auto& tmpConfigs) {
+          ASSERT_EQ(Error::NONE, tmpError);
+
+          configs = tmpConfigs;
+          ASSERT_FALSE(configs.empty());
+        });
+
+    return configs;
+  }
+
+  std::vector<ColorMode> getColorModes() {
+    std::vector<ColorMode> modes;
+    mComposerClient->getColorModes(
+        mPrimaryDisplay, [&](const auto& tmpError, const auto& tmpModes) {
+          ASSERT_EQ(Error::NONE, tmpError);
+
+          modes = tmpModes;
+          ASSERT_NE(modes.end(),
+                    std::find(modes.begin(), modes.end(), ColorMode::NATIVE));
+        });
+
+    return modes;
+  }
+
+  std::vector<IComposerClient::PowerMode> getPowerModes() {
+    std::vector<IComposerClient::PowerMode> modes;
+    modes.push_back(IComposerClient::PowerMode::OFF);
+
+    mComposerClient->getDozeSupport(
+        mPrimaryDisplay, [&](const auto& tmpError, const auto& tmpSupport) {
+          ASSERT_EQ(Error::NONE, tmpError);
+          if (tmpSupport) {
+            modes.push_back(IComposerClient::PowerMode::DOZE);
+            modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND);
+          }
+        });
+
+    // push ON last
+    modes.push_back(IComposerClient::PowerMode::ON);
+
+    return modes;
+  }
+
+  void setActiveConfig(Config config) {
+    auto ret = mComposerClient->setActiveConfig(mPrimaryDisplay, config);
+    ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+  }
+
+  void setColorMode(ColorMode mode) {
+    auto ret = mComposerClient->setColorMode(mPrimaryDisplay, mode);
+    ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+  }
+
+  void setPowerMode(IComposerClient::PowerMode mode) {
+    auto ret = mComposerClient->setPowerMode(mPrimaryDisplay, mode);
+    ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+  }
+
+  void setVsyncEnabled(bool enable) {
+    auto ret = mComposerClient->setVsyncEnabled(
+        mPrimaryDisplay,
+        enable ? IComposerClient::Vsync::ENABLE
+               : IComposerClient::Vsync::DISABLE);
+    ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+  }
+  // use the slot count usually set by SF
+  static constexpr uint32_t kBufferSlotCount = 64;
+
+  sp<IComposer> mComposer;
+  sp<IComposerClient> mComposerClient;
+  sp<GraphicsComposerCallback> mComposerCallback;
+  // the first display and is assumed never to be removed
+  Display mPrimaryDisplay;
+
+ private:
+  sp<IComposerClient> createClient() {
+    sp<IComposerClient> client;
+    mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {
+      if (tmpError == Error::NONE) {
+        client = tmpClient;
+      }
+    });
+
+    return client;
+  }
+
+  Display waitForFirstDisplay() {
+    while (true) {
+      std::vector<Display> displays = mComposerCallback->getDisplays();
+      if (displays.empty()) {
+        usleep(5 * 1000);
+        continue;
+      }
+
+      return displays[0];
+    }
+  }
+
+  // the set of all supported capabilities
+  std::unordered_set<IComposer::Capability> mCapabilities;
+};
+
+/**
+ * Test IComposer::getCapabilities.
+ *
+ * Test that IComposer::getCapabilities returns no invalid capabilities.
+ */
+TEST_F(GraphicsComposerHidlTest, GetCapabilities) {
+  mComposer->getCapabilities([](const auto& tmpCapabilities) {
+    std::vector<IComposer::Capability> capabilities = tmpCapabilities;
+    ASSERT_EQ(capabilities.end(),
+              std::find(capabilities.begin(), capabilities.end(),
+                        IComposer::Capability::INVALID));
+  });
+}
+
+/**
+ * Test IComposer::dumpDebugInfo.
+ */
+TEST_F(GraphicsComposerHidlTest, DumpDebugInfo) {
+  mComposer->dumpDebugInfo([](const auto&) {
+    // nothing to do
+  });
+}
+
+/**
+ * Test IComposer::createClient.
+ *
+ * Test that IComposerClient is a singleton.
+ */
+TEST_F(GraphicsComposerHidlTest, CreateClientSingleton) {
+  mComposer->createClient([&](const auto& tmpError, const auto&) {
+    EXPECT_EQ(Error::NO_RESOURCES, tmpError);
+  });
+}
+
+/**
+ * Test IComposerClient::createVirtualDisplay and
+ * IComposerClient::destroyVirtualDisplay.
+ *
+ * Test that virtual displays can be created and has the correct display type.
+ */
+TEST_F(GraphicsComposerHidlTest, CreateVirtualDisplay) {
+  Display display;
+  Error err = createVirtualDisplay(&display);
+  if (err == Error::UNSUPPORTED) {
+    GTEST_SUCCEED() << "no virtual display support";
+    return;
+  }
+  ASSERT_EQ(Error::NONE, err);
+
+  // test display type
+  IComposerClient::DisplayType type = getDisplayType(display);
+  EXPECT_EQ(IComposerClient::DisplayType::VIRTUAL, type);
+
+  destroyVirtualDisplay(display);
+}
+
+/**
+ * Test IComposerClient::createLayer and IComposerClient::destroyLayer.
+ *
+ * Test that layers can be created and destroyed.
+ */
+TEST_F(GraphicsComposerHidlTest, CreateLayer) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::getDisplayName.
+ */
+TEST_F(GraphicsComposerHidlTest, GetDisplayName) {
+  mComposerClient->getDisplayName(mPrimaryDisplay,
+                                  [&](const auto& tmpError, const auto&) {
+                                    ASSERT_EQ(Error::NONE, tmpError);
+                                  });
+}
+
+/**
+ * Test IComposerClient::getDisplayType.
+ *
+ * Test that IComposerClient::getDisplayType returns the correct display type
+ * for the primary display.
+ */
+TEST_F(GraphicsComposerHidlTest, GetDisplayType) {
+  IComposerClient::DisplayType type = getDisplayType(mPrimaryDisplay);
+  EXPECT_EQ(IComposerClient::DisplayType::PHYSICAL, type);
+}
+
+/**
+ * Test IComposerClient::getClientTargetSupport.
+ *
+ * Test that IComposerClient::getClientTargetSupport returns true for the
+ * required client targets.
+ */
+TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport) {
+  std::vector<Config> configs = getDisplayConfigs();
+  for (auto config : configs) {
+    int32_t width =
+        getDisplayAttribute(config, IComposerClient::Attribute::WIDTH);
+    int32_t height =
+        getDisplayAttribute(config, IComposerClient::Attribute::HEIGHT);
+    ASSERT_LT(0, width);
+    ASSERT_LT(0, height);
+
+    setActiveConfig(config);
+
+    auto ret = mComposerClient->getClientTargetSupport(
+        mPrimaryDisplay, width, height, PixelFormat::RGBA_8888,
+        Dataspace::UNKNOWN);
+    ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+  }
+}
+
+/**
+ * Test IComposerClient::getDisplayAttribute.
+ *
+ * Test that IComposerClient::getDisplayAttribute succeeds for the required
+ * formats, and succeeds or fails correctly for optional attributes.
+ */
+TEST_F(GraphicsComposerHidlTest, GetDisplayAttribute) {
+  std::vector<Config> configs = getDisplayConfigs();
+  for (auto config : configs) {
+    const std::array<IComposerClient::Attribute, 3> requiredAttributes = {{
+        IComposerClient::Attribute::WIDTH, IComposerClient::Attribute::HEIGHT,
+        IComposerClient::Attribute::VSYNC_PERIOD,
+    }};
+    for (auto attribute : requiredAttributes) {
+      getDisplayAttribute(config, attribute);
+    }
+
+    const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{
+        IComposerClient::Attribute::DPI_X, IComposerClient::Attribute::DPI_Y,
+    }};
+    for (auto attribute : optionalAttributes) {
+      mComposerClient->getDisplayAttribute(
+          mPrimaryDisplay, config, attribute,
+          [&](const auto& tmpError, const auto&) {
+            EXPECT_TRUE(tmpError == Error::NONE ||
+                        tmpError == Error::UNSUPPORTED);
+          });
+    }
+  }
+}
+
+/**
+ * Test IComposerClient::getHdrCapabilities.
+ */
+TEST_F(GraphicsComposerHidlTest, GetHdrCapabilities) {
+  mComposerClient->getHdrCapabilities(
+      mPrimaryDisplay,
+      [&](const auto& tmpError, const auto&, const auto&, const auto&,
+          const auto&) { ASSERT_EQ(Error::NONE, tmpError); });
+}
+
+/**
+ * Test IComposerClient::setClientTargetSlotCount.
+ */
+TEST_F(GraphicsComposerHidlTest, SetClientTargetSlotCount) {
+  auto ret = mComposerClient->setClientTargetSlotCount(mPrimaryDisplay,
+                                                       kBufferSlotCount);
+  ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+}
+
+/**
+ * Test IComposerClient::setActiveConfig.
+ *
+ * Test that IComposerClient::setActiveConfig succeeds for all display
+ * configs.
+ */
+TEST_F(GraphicsComposerHidlTest, SetActiveConfig) {
+  std::vector<Config> configs = getDisplayConfigs();
+  for (auto config : configs) {
+    setActiveConfig(config);
+
+    mComposerClient->getActiveConfig(
+        mPrimaryDisplay, [&](const auto& tmpError, const auto& tmpConfig) {
+          EXPECT_EQ(Error::NONE, tmpError);
+          EXPECT_EQ(config, tmpConfig);
+        });
+  }
+}
+
+/**
+ * Test IComposerClient::setColorMode.
+ *
+ * Test that IComposerClient::setColorMode succeeds for all color modes.
+ */
+TEST_F(GraphicsComposerHidlTest, SetColorMode) {
+  std::vector<ColorMode> modes = getColorModes();
+  for (auto mode : modes) {
+    setColorMode(mode);
+  }
+}
+
+/**
+ * Test IComposerClient::setPowerMode.
+ *
+ * Test that IComposerClient::setPowerMode succeeds for all power modes.
+ */
+TEST_F(GraphicsComposerHidlTest, SetPowerMode) {
+  std::vector<IComposerClient::PowerMode> modes = getPowerModes();
+  for (auto mode : modes) {
+    setPowerMode(mode);
+  }
+}
+
+/**
+ * Test IComposerClient::setVsyncEnabled.
+ *
+ * Test that IComposerClient::setVsyncEnabled succeeds and there is no
+ * spurious vsync events.
+ */
+TEST_F(GraphicsComposerHidlTest, SetVsyncEnabled) {
+  mComposerCallback->setVsyncAllowed(true);
+
+  setVsyncEnabled(true);
+  usleep(60 * 1000);
+  setVsyncEnabled(false);
+
+  mComposerCallback->setVsyncAllowed(false);
+}
+
+// Tests for IComposerClient::Command.
+class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
+ protected:
+  void SetUp() override {
+    ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
+    ASSERT_NO_FATAL_FAILURE(SetUpGralloc());
+
+    mWriter = std::make_unique<CommandWriterBase>(1024);
+    mReader = std::make_unique<CommandReader>();
+  }
+
+  void TearDown() override {
+    ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
+  }
+
+  const native_handle_t* cloneBuffer(const native_handle_t* handle) {
+    auto clone = native_handle_clone(handle);
+    if (!clone) {
+      return nullptr;
+    }
+
+    GrallocError err = mMapper->retain(clone);
+    if (err != GrallocError::NONE) {
+      native_handle_close(clone);
+      native_handle_delete(const_cast<native_handle_t*>(clone));
+      return nullptr;
+    }
+
+    return clone;
+  }
+
+  const native_handle_t* allocate(
+      const IAllocatorClient::BufferDescriptorInfo& info) {
+    // create descriptor
+    GrallocError err = GrallocError::NO_RESOURCES;
+    BufferDescriptor descriptor;
+    mAllocatorClient->createDescriptor(
+        info, [&](const auto& tmpError, const auto& tmpDescriptor) {
+          err = tmpError;
+          descriptor = tmpDescriptor;
+        });
+    if (err != GrallocError::NONE) {
+      return nullptr;
+    }
+
+    // allocate buffer
+    hidl_vec<BufferDescriptor> descriptors;
+    hidl_vec<Buffer> buffers;
+    descriptors.setToExternal(&descriptor, 1);
+    err = GrallocError::NO_RESOURCES;
+    mAllocatorClient->allocate(
+        descriptors, [&](const auto& tmpError, const auto& tmpBuffers) {
+          err = tmpError;
+          buffers = tmpBuffers;
+        });
+    if ((err != GrallocError::NONE && err != GrallocError::NOT_SHARED) ||
+        buffers.size() != 1) {
+      mAllocatorClient->destroyDescriptor(descriptors[0]);
+      return nullptr;
+    }
+
+    // export handle
+    err = GrallocError::NO_RESOURCES;
+    const native_handle_t* handle = nullptr;
+    mAllocatorClient->exportHandle(
+        descriptors[0], buffers[0],
+        [&](const auto& tmpError, const auto& tmpHandle) {
+          err = tmpError;
+          if (err != GrallocError::NONE) {
+            return;
+          }
+
+          handle = cloneBuffer(tmpHandle.getNativeHandle());
+          if (!handle) {
+            err = GrallocError::NO_RESOURCES;
+            return;
+          }
+        });
+
+    mAllocatorClient->destroyDescriptor(descriptors[0]);
+    mAllocatorClient->free(buffers[0]);
+
+    if (err != GrallocError::NONE) {
+      return nullptr;
+    }
+
+    return handle;
+  }
+
+  const native_handle_t* allocate() {
+    IAllocatorClient::BufferDescriptorInfo info{};
+    info.width = 64;
+    info.height = 64;
+    info.layerCount = 1;
+    info.format = PixelFormat::RGBA_8888;
+    info.producerUsageMask = static_cast<uint64_t>(ProducerUsage::CPU_WRITE);
+    info.consumerUsageMask = static_cast<uint64_t>(ConsumerUsage::CPU_READ);
+
+    return allocate(info);
+  }
+
+  void free(const native_handle_t* handle) {
+    auto ret = mMapper->release(handle);
+    ASSERT_EQ(GrallocError::NONE, static_cast<GrallocError>(ret));
+  }
+
+  void execute() {
+    bool queueChanged = false;
+    uint32_t commandLength = 0;
+    hidl_vec<hidl_handle> commandHandles;
+    ASSERT_TRUE(
+        mWriter->writeQueue(&queueChanged, &commandLength, &commandHandles));
+
+    if (queueChanged) {
+      auto ret =
+          mComposerClient->setInputCommandQueue(*mWriter->getMQDescriptor());
+      ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+      return;
+    }
+
+    mComposerClient->executeCommands(
+        commandLength, commandHandles,
+        [&](const auto& tmpError, const auto& tmpOutQueueChanged,
+            const auto& tmpOutLength, const auto& tmpOutHandles) {
+          ASSERT_EQ(Error::NONE, tmpError);
+
+          if (tmpOutQueueChanged) {
+            mComposerClient->getOutputCommandQueue(
+                [&](const auto& tmpError, const auto& tmpDescriptor) {
+                  ASSERT_EQ(Error::NONE, tmpError);
+                  mReader->setMQDescriptor(tmpDescriptor);
+                });
+          }
+
+          ASSERT_TRUE(mReader->readQueue(tmpOutLength, tmpOutHandles));
+          mReader->parse();
+        });
+  }
+
+  // A command parser that checks that no error nor unexpected commands are
+  // returned.
+  class CommandReader : public CommandReaderBase {
+   public:
+    // Parse all commands in the return command queue.  Call GTEST_FAIL() for
+    // unexpected errors or commands.
+    void parse() {
+      while (!isEmpty()) {
+        IComposerClient::Command command;
+        uint16_t length;
+        ASSERT_TRUE(beginCommand(&command, &length));
+
+        switch (command) {
+          case IComposerClient::Command::SET_ERROR: {
+            ASSERT_EQ(2, length);
+            auto loc = read();
+            auto err = readSigned();
+            GTEST_FAIL() << "unexpected error " << err << " at location "
+                         << loc;
+          } break;
+          case IComposerClient::Command::SELECT_DISPLAY:
+          case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
+          case IComposerClient::Command::SET_DISPLAY_REQUESTS:
+          case IComposerClient::Command::SET_PRESENT_FENCE:
+          case IComposerClient::Command::SET_RELEASE_FENCES:
+            break;
+          default:
+            GTEST_FAIL() << "unexpected return command " << std::hex
+                         << static_cast<int>(command);
+            break;
+        }
+
+        endCommand();
+      }
+    }
+  };
+
+  std::unique_ptr<CommandWriterBase> mWriter;
+  std::unique_ptr<CommandReader> mReader;
+
+ private:
+  void SetUpGralloc() {
+    mAllocator = IAllocator::getService("gralloc");
+    ASSERT_NE(nullptr, mAllocator.get());
+
+    mAllocator->createClient([this](const auto& error, const auto& client) {
+      if (error == GrallocError::NONE) {
+        mAllocatorClient = client;
+      }
+    });
+    ASSERT_NE(nullptr, mAllocatorClient.get());
+
+    mMapper = IMapper::getService("gralloc-mapper");
+    ASSERT_NE(nullptr, mMapper.get());
+    ASSERT_FALSE(mMapper->isRemote());
+  }
+
+  sp<IAllocator> mAllocator;
+  sp<IAllocatorClient> mAllocatorClient;
+  sp<IMapper> mMapper;
+};
+
+/**
+ * Test IComposerClient::Command::SET_COLOR_TRANSFORM.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_COLOR_TRANSFORM) {
+  const std::array<float, 16> identity = {{
+      1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+      0.0f, 0.0f, 0.0f, 1.0f,
+  }};
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->setColorTransform(identity.data(), ColorTransform::IDENTITY);
+
+  execute();
+}
+
+/**
+ * Test IComposerClient::Command::SET_CLIENT_TARGET.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_CLIENT_TARGET) {
+  mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->setClientTarget(0, nullptr, -1, Dataspace::UNKNOWN,
+                           std::vector<IComposerClient::Rect>());
+
+  execute();
+}
+
+/**
+ * Test IComposerClient::Command::SET_OUTPUT_BUFFER.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_OUTPUT_BUFFER) {
+  auto handle = allocate();
+  ASSERT_NE(nullptr, handle);
+
+  Display display;
+  Error err = createVirtualDisplay(&display);
+  if (err == Error::UNSUPPORTED) {
+    GTEST_SUCCEED() << "no virtual display support";
+    return;
+  }
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(display);
+  mWriter->setOutputBuffer(0, handle, -1);
+
+  destroyVirtualDisplay(display);
+  free(handle);
+}
+
+/**
+ * Test IComposerClient::Command::VALIDATE_DISPLAY.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, VALIDATE_DISPLAY) {
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->validateDisplay();
+  execute();
+}
+
+/**
+ * Test IComposerClient::Command::ACCEPT_DISPLAY_CHANGES.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, ACCEPT_DISPLAY_CHANGES) {
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->validateDisplay();
+  mWriter->acceptDisplayChanges();
+  execute();
+}
+
+/**
+ * Test IComposerClient::Command::PRESENT_DISPLAY.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, PRESENT_DISPLAY) {
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->validateDisplay();
+  mWriter->presentDisplay();
+  execute();
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_CURSOR_POSITION.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_CURSOR_POSITION) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerCursorPosition(1, 1);
+  mWriter->setLayerCursorPosition(0, 0);
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_BUFFER.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER) {
+  auto handle = allocate();
+  ASSERT_NE(nullptr, handle);
+
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerBuffer(0, handle, -1);
+  execute();
+
+  destroyLayer(layer);
+  free(handle);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_SURFACE_DAMAGE) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  IComposerClient::Rect empty{0, 0, 0, 0};
+  IComposerClient::Rect unit{0, 0, 1, 1};
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, empty));
+  mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, unit));
+  mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>());
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_BLEND_MODE.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_BLEND_MODE) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE);
+  mWriter->setLayerBlendMode(IComposerClient::BlendMode::PREMULTIPLIED);
+  mWriter->setLayerBlendMode(IComposerClient::BlendMode::COVERAGE);
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_COLOR.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_COLOR) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerColor(IComposerClient::Color{0xff, 0xff, 0xff, 0xff});
+  mWriter->setLayerColor(IComposerClient::Color{0, 0, 0, 0});
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_COMPOSITION_TYPE) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerCompositionType(IComposerClient::Composition::CLIENT);
+  mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
+  mWriter->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
+  mWriter->setLayerCompositionType(IComposerClient::Composition::CURSOR);
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_DATASPACE.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_DATASPACE) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_DISPLAY_FRAME.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_DISPLAY_FRAME) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerDisplayFrame(IComposerClient::Rect{0, 0, 1, 1});
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_PLANE_ALPHA.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PLANE_ALPHA) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerPlaneAlpha(0.0f);
+  mWriter->setLayerPlaneAlpha(1.0f);
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_SIDEBAND_STREAM) {
+  if (!hasCapability(IComposer::Capability::SIDEBAND_STREAM)) {
+    GTEST_SUCCEED() << "no sideband stream support";
+    return;
+  }
+
+  auto handle = allocate();
+  ASSERT_NE(nullptr, handle);
+
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerSidebandStream(handle);
+  execute();
+
+  destroyLayer(layer);
+  free(handle);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_SOURCE_CROP.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_SOURCE_CROP) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerSourceCrop(IComposerClient::FRect{0.0f, 0.0f, 1.0f, 1.0f});
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_TRANSFORM.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_TRANSFORM) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerTransform(static_cast<Transform>(0));
+  mWriter->setLayerTransform(Transform::FLIP_H);
+  mWriter->setLayerTransform(Transform::FLIP_V);
+  mWriter->setLayerTransform(Transform::ROT_90);
+  mWriter->setLayerTransform(Transform::ROT_180);
+  mWriter->setLayerTransform(Transform::ROT_270);
+  mWriter->setLayerTransform(
+      static_cast<Transform>(Transform::FLIP_H | Transform::ROT_90));
+  mWriter->setLayerTransform(
+      static_cast<Transform>(Transform::FLIP_V | Transform::ROT_90));
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_VISIBLE_REGION.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_VISIBLE_REGION) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  IComposerClient::Rect empty{0, 0, 0, 0};
+  IComposerClient::Rect unit{0, 0, 1, 1};
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, empty));
+  mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, unit));
+  mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>());
+  execute();
+
+  destroyLayer(layer);
+}
+
+/**
+ * Test IComposerClient::Command::SET_LAYER_Z_ORDER.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_Z_ORDER) {
+  Layer layer;
+  Error err = createLayer(&layer);
+  ASSERT_EQ(Error::NONE, err);
+
+  mWriter->selectDisplay(mPrimaryDisplay);
+  mWriter->selectLayer(layer);
+  mWriter->setLayerZOrder(10);
+  mWriter->setLayerZOrder(0);
+  execute();
+
+  destroyLayer(layer);
+}
+
+}  // namespace anonymous
+}  // namespace tests
+}  // namespace V2_1
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+
+  return status;
+}
diff --git a/graphics/composer/2.1/vts/functional/vts/testcases/hal/graphics/composer/hidl/target/Android.mk b/graphics/composer/2.1/vts/functional/vts/testcases/hal/graphics/composer/hidl/target/Android.mk
new file mode 100644
index 0000000..bafb67f
--- /dev/null
+++ b/graphics/composer/2.1/vts/functional/vts/testcases/hal/graphics/composer/hidl/target/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := HalGraphicsComposerHidlTargetTest
+VTS_CONFIG_SRC_DIR := testcases/hal/graphics/composer/hidl/target
+include test/vts/tools/build/Android.host_config.mk
diff --git a/graphics/composer/2.1/vts/functional/vts/testcases/hal/graphics/composer/hidl/target/AndroidTest.xml b/graphics/composer/2.1/vts/functional/vts/testcases/hal/graphics/composer/hidl/target/AndroidTest.xml
new file mode 100644
index 0000000..e807f54
--- /dev/null
+++ b/graphics/composer/2.1/vts/functional/vts/testcases/hal/graphics/composer/hidl/target/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS Graphics Composer HIDL HAL's basic target-side test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="push-group" value="HidlHalTest.push" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="HalGraphicsComposerHidlTargetTest" />
+        <option name="binary-test-sources" value="
+            _32bit::DATA/nativetest/graphics_composer_hidl_hal_test/graphics_composer_hidl_hal_test,
+            _64bit::DATA/nativetest64/graphics_composer_hidl_hal_test/graphics_composer_hidl_hal_test,
+	    " />
+        <option name="binary-test-type" value="gtest" />
+        <option name="test-timeout" value="1m" />
+    </test>
+</configuration>
diff --git a/graphics/composer/2.1/vts/types.vts b/graphics/composer/2.1/vts/types.vts
new file mode 100644
index 0000000..ccbd9d8
--- /dev/null
+++ b/graphics/composer/2.1/vts/types.vts
@@ -0,0 +1,48 @@
+component_class: HAL_HIDL
+component_type_version: 2.1
+component_name: "types"
+
+package: "android.hardware.graphics.composer"
+
+
+attribute: {
+    name: "::android::hardware::graphics::composer::V2_1::Error"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "int32_t"
+
+        enumerator: "NONE"
+        scalar_value: {
+            int32_t: 0
+        }
+        enumerator: "BAD_CONFIG"
+        scalar_value: {
+            int32_t: 1
+        }
+        enumerator: "BAD_DISPLAY"
+        scalar_value: {
+            int32_t: 2
+        }
+        enumerator: "BAD_LAYER"
+        scalar_value: {
+            int32_t: 3
+        }
+        enumerator: "BAD_PARAMETER"
+        scalar_value: {
+            int32_t: 4
+        }
+        enumerator: "NO_RESOURCES"
+        scalar_value: {
+            int32_t: 6
+        }
+        enumerator: "NOT_VALIDATED"
+        scalar_value: {
+            int32_t: 7
+        }
+        enumerator: "UNSUPPORTED"
+        scalar_value: {
+            int32_t: 8
+        }
+    }
+}
+
diff --git a/graphics/composer/Android.mk b/graphics/composer/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/graphics/composer/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/power/1.0/types.hal b/power/1.0/types.hal
index c27242e..debdc35 100644
--- a/power/1.0/types.hal
+++ b/power/1.0/types.hal
@@ -76,15 +76,6 @@
     * it has been launched.
     */
     LAUNCH = 0x00000008,
-
-   /*
-    * When device enters some special modes, e.g. theater mode in Android
-    * Wear, there is no touch interaction expected between device and user.
-    * Touch controller could be disabled in those modes to save power.
-    * The data parameter is non-zero when touch could be disabled, and zero
-    * when touch needs to be re-enabled.
-    */
-    DISABLE_TOUCH = 0x00000009
 };
 
 enum Feature : uint32_t {
diff --git a/power/1.0/vts/functional/power_hidl_hal_test.cpp b/power/1.0/vts/functional/power_hidl_hal_test.cpp
index 3f0ef56..b114944 100644
--- a/power/1.0/vts/functional/power_hidl_hal_test.cpp
+++ b/power/1.0/vts/functional/power_hidl_hal_test.cpp
@@ -62,7 +62,7 @@
                 PowerHint::VIDEO_ENCODE,  PowerHint::VIDEO_DECODE,
                 PowerHint::LOW_POWER,     PowerHint::SUSTAINED_PERFORMANCE,
                 PowerHint::VR_MODE,       PowerHint::LAUNCH,
-                PowerHint::DISABLE_TOUCH, badHint};
+                badHint};
   Return<void> ret;
   for (auto hint : hints) {
     ret = power->powerHint(hint, 1);
diff --git a/power/1.0/vts/types.vts b/power/1.0/vts/types.vts
index 94c003b..5724946 100644
--- a/power/1.0/vts/types.vts
+++ b/power/1.0/vts/types.vts
@@ -43,10 +43,6 @@
         scalar_value: {
             uint32_t: 8
         }
-        enumerator: "DISABLE_TOUCH"
-        scalar_value: {
-            uint32_t: 9
-        }
     }
 }
 
diff --git a/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target/AndroidTest.xml b/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target/AndroidTest.xml
index 9339165..d450315 100644
--- a/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target/AndroidTest.xml
+++ b/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target/AndroidTest.xml
@@ -26,7 +26,8 @@
             "/>
         <option name="test-config-path" value="vts/testcases/hal/soundtrigger/hidl/target/HalSoundTriggerHidlTargetBasicTest.config" />
         <option name="binary-test-type" value="hal_hidl_gtest" />
-        <option name="precondition-file-path-prefix" value="*/lib/hw/sound_trigger.primary." />
+        <option name="precondition-file-path-prefix" value="/*/lib/hw/sound_trigger.primary." />
+        <option name="skip-on-64bit-abi" value="true" />
         <option name="test-timeout" value="1m" />
     </test>
 </configuration>
diff --git a/vehicle/2.0/default/Android.mk b/vehicle/2.0/default/Android.mk
index 4a27eeb..9c75006 100644
--- a/vehicle/2.0/default/Android.mk
+++ b/vehicle/2.0/default/Android.mk
@@ -23,6 +23,7 @@
 LOCAL_MODULE := $(module_prefix)-manager-lib
 LOCAL_SRC_FILES := \
     vehicle_hal_manager/AccessControlConfigParser.cpp \
+    vehicle_hal_manager/Obd2SensorStore.cpp \
     vehicle_hal_manager/SubscriptionManager.cpp \
     vehicle_hal_manager/VehicleHalManager.cpp \
     vehicle_hal_manager/VehicleObjectPool.cpp \
@@ -71,6 +72,7 @@
 
 LOCAL_SRC_FILES:= \
     tests/AccessControlConfigParser_test.cpp \
+    tests/Obd2SensorStore_test.cpp \
     tests/SubscriptionManager_test.cpp \
     tests/VehicleHalManager_test.cpp \
     tests/VehicleObjectPool_test.cpp \
diff --git a/vehicle/2.0/default/impl/DefaultConfig.h b/vehicle/2.0/default/impl/DefaultConfig.h
index 85bba2c..c74ddc0 100644
--- a/vehicle/2.0/default/impl/DefaultConfig.h
+++ b/vehicle/2.0/default/impl/DefaultConfig.h
@@ -165,12 +165,14 @@
         .prop = toInt(VehicleProperty::OBD2_LIVE_FRAME),
         .access = VehiclePropertyAccess::READ,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .configArray = {0,0}
     },
 
     {
         .prop = toInt(VehicleProperty::OBD2_FREEZE_FRAME),
         .access = VehiclePropertyAccess::READ,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .configArray = {0,0}
     }
 };
 
diff --git a/vehicle/2.0/default/impl/DefaultVehicleHal.cpp b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
index 65bd49d..c6cf9b9 100644
--- a/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
+++ b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
@@ -16,6 +16,8 @@
 
 #include "DefaultVehicleHal.h"
 
+#include <algorithm>
+
 #define LOG_TAG "default_vehicle"
 #include <android/log.h>
 
@@ -153,6 +155,96 @@
     return status;
 }
 
+void DefaultVehicleHal::onCreate() {
+    const auto& propConfigs(listProperties());
+    auto obd2LiveFramePropConfig = std::find_if(
+        propConfigs.begin(),
+        propConfigs.end(),
+        [] (VehiclePropConfig config) -> bool {
+            return (config.prop == VehicleProperty::OBD2_LIVE_FRAME);
+        });
+    mObd2SensorStore.reset(new Obd2SensorStore(
+        obd2LiveFramePropConfig->configArray[0],
+        obd2LiveFramePropConfig->configArray[1]));
+    // precalculate OBD2 sensor values
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::FUEL_SYSTEM_STATUS,
+        toInt(FuelSystemStatus::CLOSED_LOOP));
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON, 0);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::IGNITION_MONITORS_SUPPORTED,
+        toInt(IgnitionMonitorKind::SPARK));
+    mObd2SensorStore->setIntegerSensor(Obd2IntegerSensorIndex::IGNITION_SPECIFIC_MONITORS,
+        CommonIgnitionMonitors::COMPONENTS_AVAILABLE |
+        CommonIgnitionMonitors::MISFIRE_AVAILABLE |
+        SparkIgnitionMonitors::AC_REFRIGERANT_AVAILABLE |
+        SparkIgnitionMonitors::EVAPORATIVE_SYSTEM_AVAILABLE);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::INTAKE_AIR_TEMPERATURE, 35);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::COMMANDED_SECONDARY_AIR_STATUS,
+        toInt(SecondaryAirStatus::FROM_OUTSIDE_OR_OFF));
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT, 1);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::RUNTIME_SINCE_ENGINE_START, 500);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON, 0);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::WARMUPS_SINCE_CODES_CLEARED, 51);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::DISTANCE_TRAVELED_SINCE_CODES_CLEARED, 365);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE, 30);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::CONTROL_MODULE_VOLTAGE, 12);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::AMBIENT_AIR_TEMPERATURE, 18);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::MAX_FUEL_AIR_EQUIVALENCE_RATIO, 1);
+    mObd2SensorStore->setIntegerSensor(
+        Obd2IntegerSensorIndex::FUEL_TYPE, toInt(FuelType::GASOLINE));
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::CALCULATED_ENGINE_LOAD, 0.153);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1, -0.16);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1, -0.16);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK2, -0.16);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK2, -0.16);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::INTAKE_MANIFOLD_ABSOLUTE_PRESSURE, 7.5);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::ENGINE_RPM, 1250.);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::VEHICLE_SPEED, 40.);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::TIMING_ADVANCE, 2.5);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::THROTTLE_POSITION, 19.75);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::OXYGEN_SENSOR1_VOLTAGE, 0.265);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::FUEL_TANK_LEVEL_INPUT, 0.824);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::EVAPORATION_SYSTEM_VAPOR_PRESSURE, -0.373);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::CATALYST_TEMPERATURE_BANK1_SENSOR1, 190.);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::RELATIVE_THROTTLE_POSITION, 3.);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::ABSOLUTE_THROTTLE_POSITION_B, 0.306);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::ACCELERATOR_PEDAL_POSITION_D, 0.188);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::ACCELERATOR_PEDAL_POSITION_E, 0.094);
+    mObd2SensorStore->setFloatSensor(
+        Obd2FloatSensorIndex::COMMANDED_THROTTLE_ACTUATOR, 0.024);
+}
+
 StatusCode DefaultVehicleHal::getHvacTemperature(int32_t areaId,
                                                  float* outValue)  {
     if (areaId == toInt(VehicleAreaZone::ROW_1_LEFT)) {
@@ -205,73 +297,17 @@
     return StatusCode::OK;
 }
 
-static std::vector<int32_t> fillObd2IntValues() {
-    std::vector<int32_t> intValues(toInt(Obd2IntegerSensorIndex::LAST_SYSTEM_INDEX));
-#define SENSOR(name) toInt(Obd2IntegerSensorIndex:: name)
-    intValues[SENSOR(FUEL_SYSTEM_STATUS)] = toInt(FuelSystemStatus::CLOSED_LOOP);
-    intValues[SENSOR(MALFUNCTION_INDICATOR_LIGHT_ON)] = 0;
-    intValues[SENSOR(IGNITION_MONITORS_SUPPORTED)] = toInt(IgnitionMonitorKind::SPARK);
-    intValues[SENSOR(IGNITION_SPECIFIC_MONITORS)] =
-        CommonIgnitionMonitors::COMPONENTS_AVAILABLE |
-        CommonIgnitionMonitors::MISFIRE_AVAILABLE |
-        SparkIgnitionMonitors::AC_REFRIGERANT_AVAILABLE |
-        SparkIgnitionMonitors::EVAPORATIVE_SYSTEM_AVAILABLE;
-    intValues[SENSOR(INTAKE_AIR_TEMPERATURE)] = 35;
-    intValues[SENSOR(COMMANDED_SECONDARY_AIR_STATUS)] =
-        toInt(SecondaryAirStatus::FROM_OUTSIDE_OR_OFF);
-    intValues[SENSOR(NUM_OXYGEN_SENSORS_PRESENT)] = 1;
-    intValues[SENSOR(RUNTIME_SINCE_ENGINE_START)] = 500;
-    intValues[SENSOR(DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON)] = 0;
-    intValues[SENSOR(WARMUPS_SINCE_CODES_CLEARED)] = 51;
-    intValues[SENSOR(DISTANCE_TRAVELED_SINCE_CODES_CLEARED)] = 365;
-    intValues[SENSOR(ABSOLUTE_BAROMETRIC_PRESSURE)] = 30;
-    intValues[SENSOR(CONTROL_MODULE_VOLTAGE)] = 12;
-    intValues[SENSOR(AMBIENT_AIR_TEMPERATURE)] = 18;
-    intValues[SENSOR(MAX_FUEL_AIR_EQUIVALENCE_RATIO)] = 1;
-    intValues[SENSOR(FUEL_TYPE)] = toInt(FuelType::GASOLINE);
-#undef SENSOR
-    return intValues;
-}
-
-static std::vector<float> fillObd2FloatValues() {
-    std::vector<float> floatValues(toInt(Obd2FloatSensorIndex::LAST_SYSTEM_INDEX));
-#define SENSOR(name) toInt(Obd2FloatSensorIndex:: name)
-    floatValues[SENSOR(CALCULATED_ENGINE_LOAD)] = 0.153;
-    floatValues[SENSOR(SHORT_TERM_FUEL_TRIM_BANK1)] = -0.16;
-    floatValues[SENSOR(LONG_TERM_FUEL_TRIM_BANK1)] = -0.16;
-    floatValues[SENSOR(SHORT_TERM_FUEL_TRIM_BANK2)] = -0.16;
-    floatValues[SENSOR(LONG_TERM_FUEL_TRIM_BANK2)] = -0.16;
-    floatValues[SENSOR(INTAKE_MANIFOLD_ABSOLUTE_PRESSURE)] = 7.5;
-    floatValues[SENSOR(ENGINE_RPM)] = 1250.;
-    floatValues[SENSOR(VEHICLE_SPEED)] = 40.;
-    floatValues[SENSOR(TIMING_ADVANCE)] = 2.5;
-    floatValues[SENSOR(THROTTLE_POSITION)] = 19.75;
-    floatValues[SENSOR(OXYGEN_SENSOR1_VOLTAGE)] = 0.265;
-    floatValues[SENSOR(FUEL_TANK_LEVEL_INPUT)] = 0.824;
-    floatValues[SENSOR(EVAPORATION_SYSTEM_VAPOR_PRESSURE)] = -0.373;
-    floatValues[SENSOR(CATALYST_TEMPERATURE_BANK1_SENSOR1)] = 190.;
-    floatValues[SENSOR(RELATIVE_THROTTLE_POSITION)] = 3.;
-    floatValues[SENSOR(ABSOLUTE_THROTTLE_POSITION_B)] = 0.306;
-    floatValues[SENSOR(ACCELERATOR_PEDAL_POSITION_D)] = 0.188;
-    floatValues[SENSOR(ACCELERATOR_PEDAL_POSITION_E)] = 0.094;
-    floatValues[SENSOR(COMMANDED_THROTTLE_ACTUATOR)] = 0.024;
-#undef SENSOR
-    return floatValues;
-}
-
 StatusCode DefaultVehicleHal::fillObd2LiveFrame(VehiclePropValuePtr* v) {
-    static std::vector<int32_t> intValues(fillObd2IntValues());
-    static std::vector<float> floatValues(fillObd2FloatValues());
-    (*v)->value.int32Values = intValues;
-    (*v)->value.floatValues = floatValues;
+    (*v)->value.int32Values = mObd2SensorStore->getIntegerSensors();
+    (*v)->value.floatValues = mObd2SensorStore->getFloatSensors();
+    (*v)->value.bytes = mObd2SensorStore->getSensorsBitmask();
     return StatusCode::OK;
 }
 
 StatusCode DefaultVehicleHal::fillObd2FreezeFrame(VehiclePropValuePtr* v) {
-    static std::vector<int32_t> intValues(fillObd2IntValues());
-    static std::vector<float> floatValues(fillObd2FloatValues());
-    (*v)->value.int32Values = intValues;
-    (*v)->value.floatValues = floatValues;
+    (*v)->value.int32Values = mObd2SensorStore->getIntegerSensors();
+    (*v)->value.floatValues = mObd2SensorStore->getFloatSensors();
+    (*v)->value.bytes = mObd2SensorStore->getSensorsBitmask();
     (*v)->value.stringValue = "P0010";
     return StatusCode::OK;
 }
diff --git a/vehicle/2.0/default/impl/DefaultVehicleHal.h b/vehicle/2.0/default/impl/DefaultVehicleHal.h
index b01c963..567ddf1 100644
--- a/vehicle/2.0/default/impl/DefaultVehicleHal.h
+++ b/vehicle/2.0/default/impl/DefaultVehicleHal.h
@@ -17,8 +17,11 @@
 #ifndef android_hardware_vehicle_V2_0_impl_DefaultVehicleHal_H_
 #define android_hardware_vehicle_V2_0_impl_DefaultVehicleHal_H_
 
+#include <memory>
+
 #include <VehicleHal.h>
 #include <impl/DefaultConfig.h>
+#include <vehicle_hal_manager/Obd2SensorStore.h>
 #include <utils/SystemClock.h>
 
 namespace android {
@@ -38,6 +41,8 @@
     VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
                             StatusCode* outStatus) override;
 
+    void onCreate() override;
+
     StatusCode set(const VehiclePropValue& propValue) override;
 
     StatusCode subscribe(int32_t /*property*/,
@@ -57,8 +62,8 @@
     StatusCode setHvacTemperature(int32_t areaId, float value);
     StatusCode getHvacDefroster(int32_t areaId, bool* outValue);
     StatusCode setHvacDefroster(int32_t areaId, bool value);
-    StatusCode fillObd2LiveFrame (VehiclePropValuePtr* v);
-    StatusCode fillObd2FreezeFrame (VehiclePropValuePtr* v);
+    StatusCode fillObd2LiveFrame(VehiclePropValuePtr* v);
+    StatusCode fillObd2FreezeFrame(VehiclePropValuePtr* v);
 private:
     int32_t mFanSpeed = 3;
     int32_t mBrightness = 7;
@@ -71,6 +76,7 @@
     bool mHvacAcOn = true;
     bool mHvacAutoOn = true;
     VehicleHvacFanDirection mFanDirection = VehicleHvacFanDirection::FACE;
+    std::unique_ptr<Obd2SensorStore> mObd2SensorStore{nullptr};
 };
 
 }  // impl
diff --git a/vehicle/2.0/default/tests/Obd2SensorStore_test.cpp b/vehicle/2.0/default/tests/Obd2SensorStore_test.cpp
new file mode 100644
index 0000000..6866454
--- /dev/null
+++ b/vehicle/2.0/default/tests/Obd2SensorStore_test.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ #include <gtest/gtest.h>
+
+#include "vehicle_hal_manager/Obd2SensorStore.h"
+#include "vehicle_hal_manager/VehicleUtils.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+namespace {
+
+static constexpr size_t getNumVendorIntegerSensors() {
+    return 5;
+}
+static constexpr size_t getNumVendorFloatSensors() {
+    return 3;
+}
+
+// this struct holds information necessary for a test to be able to validate
+// that the sensor bitmask contains the right data:
+//   - the index of the byte at which the bit for a given sensor lives
+//   - the expected value of that byte given that a certain sensor is present
+class BitmaskIndexingInfo {
+public:
+    size_t mByteIndex;
+    uint8_t mExpectedByteValue;
+
+    // Returns the information required to validate the bitmask for an
+    // integer-valued sensor.
+    static BitmaskIndexingInfo getForIntegerSensor(size_t index) {
+        const size_t indexInBitstream = index;
+        return getForBitstreamIndex(indexInBitstream);
+    }
+
+    // Returns the information required to validate the bitmask for a
+    // float-valued sensor.
+    static BitmaskIndexingInfo getForFloatSensor(size_t index) {
+        const size_t indexInBitstream = toInt(Obd2IntegerSensorIndex::LAST_SYSTEM_INDEX) +
+                                        1 + getNumVendorIntegerSensors() + index;
+        return getForBitstreamIndex(indexInBitstream);
+    }
+
+private:
+    static BitmaskIndexingInfo getForBitstreamIndex(size_t indexInBitstream) {
+        BitmaskIndexingInfo indexingInfo;
+        indexingInfo.mByteIndex = indexInBitstream / 8;
+        indexingInfo.mExpectedByteValue = 1 << (indexInBitstream % 8);
+        return indexingInfo;
+    }
+};
+
+static Obd2SensorStore getSensorStore() {
+    return Obd2SensorStore(getNumVendorIntegerSensors(),
+                           getNumVendorFloatSensors());
+}
+
+// Test that one can set and retrieve a value for the first integer sensor.
+TEST(Obd2SensorStoreTest, setFirstIntegerSensor) {
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setIntegerSensor(
+        Obd2IntegerSensorIndex::FUEL_SYSTEM_STATUS,
+        toInt(FuelSystemStatus::CLOSED_LOOP));
+    const auto& integerSensors(sensorStore.getIntegerSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(
+        toInt(FuelSystemStatus::CLOSED_LOOP),
+        integerSensors[toInt(Obd2IntegerSensorIndex::FUEL_SYSTEM_STATUS)]);
+    const BitmaskIndexingInfo indexingInfo(BitmaskIndexingInfo::getForIntegerSensor(
+        toInt(Obd2IntegerSensorIndex::FUEL_SYSTEM_STATUS)));
+    ASSERT_EQ(
+        indexingInfo.mExpectedByteValue,
+        sensorBitmask[indexingInfo.mByteIndex]);
+}
+
+// Test that one can set and retrieve a value for the first float sensor.
+TEST(Obd2SensorStoreTest, setFirstFloatSensor) {
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setFloatSensor(
+        Obd2FloatSensorIndex::CALCULATED_ENGINE_LOAD,
+        1.25f);
+    const auto& floatSensors(sensorStore.getFloatSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(
+        1.25f,
+        floatSensors[toInt(Obd2FloatSensorIndex::CALCULATED_ENGINE_LOAD)]);
+    const BitmaskIndexingInfo indexingInfo(BitmaskIndexingInfo::getForFloatSensor(
+        toInt(Obd2FloatSensorIndex::CALCULATED_ENGINE_LOAD)));
+    ASSERT_EQ(
+        indexingInfo.mExpectedByteValue,
+        sensorBitmask[indexingInfo.mByteIndex]);
+}
+
+// Test that one can set and retrieve a value for an integer sensor.
+TEST(Obd2SensorStoreTest, setAnyIntegerSensor) {
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setIntegerSensor(
+        Obd2IntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE,
+        4000);
+    const auto& integerSensors(sensorStore.getIntegerSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(4000,
+        integerSensors[toInt(Obd2IntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE)]);
+    const BitmaskIndexingInfo indexingInfo(BitmaskIndexingInfo::getForIntegerSensor(
+        toInt(Obd2IntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE)));
+    ASSERT_EQ(
+        indexingInfo.mExpectedByteValue,
+        sensorBitmask[indexingInfo.mByteIndex]);
+}
+
+// Test that one can set and retrieve a value for a float sensor.
+TEST(Obd2SensorStoreTest, setAnyFloatSensor) {
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setFloatSensor(
+        Obd2FloatSensorIndex::OXYGEN_SENSOR3_VOLTAGE,
+        2.5f);
+    const auto& floatSensors(sensorStore.getFloatSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(2.5f,
+        floatSensors[toInt(Obd2FloatSensorIndex::OXYGEN_SENSOR3_VOLTAGE)]);
+    const BitmaskIndexingInfo indexingInfo(BitmaskIndexingInfo::getForFloatSensor(
+        toInt(Obd2FloatSensorIndex::OXYGEN_SENSOR3_VOLTAGE)));
+    ASSERT_EQ(
+        indexingInfo.mExpectedByteValue,
+        sensorBitmask[indexingInfo.mByteIndex]);
+}
+
+// Test that one can set and retrieve a value for the last system integer sensor.
+TEST(Obd2SensorStoreTest, setLastSystemIntegerSensor) {
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setIntegerSensor(
+        Obd2IntegerSensorIndex::LAST_SYSTEM_INDEX,
+        30);
+    const auto& integerSensors(sensorStore.getIntegerSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(30,
+        integerSensors[toInt(Obd2IntegerSensorIndex::LAST_SYSTEM_INDEX)]);
+    const BitmaskIndexingInfo indexingInfo(BitmaskIndexingInfo::getForIntegerSensor(
+        toInt(Obd2IntegerSensorIndex::LAST_SYSTEM_INDEX)));
+    ASSERT_EQ(
+        indexingInfo.mExpectedByteValue,
+        sensorBitmask[indexingInfo.mByteIndex]);
+}
+
+// Test that one can set and retrieve a value for the last system float sensor.
+TEST(Obd2SensorStoreTest, setLastSystemFloatSensor) {
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setFloatSensor(
+        Obd2FloatSensorIndex::LAST_SYSTEM_INDEX,
+        2.5f);
+    const auto& floatSensors(sensorStore.getFloatSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(2.5f,
+        floatSensors[toInt(Obd2FloatSensorIndex::LAST_SYSTEM_INDEX)]);
+    const BitmaskIndexingInfo indexingInfo(BitmaskIndexingInfo::getForFloatSensor(
+        toInt(Obd2FloatSensorIndex::LAST_SYSTEM_INDEX)));
+    ASSERT_EQ(
+        indexingInfo.mExpectedByteValue,
+        sensorBitmask[indexingInfo.mByteIndex]);
+}
+
+// Test that one can set and retrieve a value for two integer sensors at once.
+TEST(Obd2SensorStoreTest, setTwoIntegerSensors) {
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setIntegerSensor(
+        Obd2IntegerSensorIndex::CONTROL_MODULE_VOLTAGE,
+        6);
+    sensorStore.setIntegerSensor(
+        Obd2IntegerSensorIndex::TIME_SINCE_TROUBLE_CODES_CLEARED,
+        1245);
+    const auto& integerSensors(sensorStore.getIntegerSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(6,
+        integerSensors[toInt(Obd2IntegerSensorIndex::CONTROL_MODULE_VOLTAGE)]);
+    ASSERT_EQ(1245,
+        integerSensors[toInt(Obd2IntegerSensorIndex::TIME_SINCE_TROUBLE_CODES_CLEARED)]);
+    const BitmaskIndexingInfo voltageIndexingInfo(BitmaskIndexingInfo::getForIntegerSensor(
+        toInt(Obd2IntegerSensorIndex::CONTROL_MODULE_VOLTAGE)));
+    const BitmaskIndexingInfo timeIndexingInfo(BitmaskIndexingInfo::getForIntegerSensor(
+        toInt(Obd2IntegerSensorIndex::TIME_SINCE_TROUBLE_CODES_CLEARED)));
+    if (voltageIndexingInfo.mByteIndex == timeIndexingInfo.mByteIndex) {
+        ASSERT_EQ(
+            voltageIndexingInfo.mExpectedByteValue |
+            timeIndexingInfo.mExpectedByteValue,
+            sensorBitmask[timeIndexingInfo.mByteIndex]);
+    }
+    else {
+        ASSERT_EQ(
+            timeIndexingInfo.mExpectedByteValue,
+            sensorBitmask[timeIndexingInfo.mByteIndex]);
+        ASSERT_EQ(
+            voltageIndexingInfo.mExpectedByteValue,
+            sensorBitmask[voltageIndexingInfo.mByteIndex]);
+    }
+}
+
+// Test that one can set and retrieve a value for two float sensors at once.
+TEST(Obd2SensorStoreTest, setTwoFloatSensors) {
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setFloatSensor(
+        Obd2FloatSensorIndex::VEHICLE_SPEED,
+        1.25f);
+    sensorStore.setFloatSensor(
+        Obd2FloatSensorIndex::MAF_AIR_FLOW_RATE,
+        2.5f);
+    const auto& floatSensors(sensorStore.getFloatSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(1.25f,
+        floatSensors[toInt(Obd2FloatSensorIndex::VEHICLE_SPEED)]);
+    ASSERT_EQ(2.5f,
+        floatSensors[toInt(Obd2FloatSensorIndex::MAF_AIR_FLOW_RATE)]);
+    const BitmaskIndexingInfo speedIndexingInfo(BitmaskIndexingInfo::getForFloatSensor(
+        toInt(Obd2FloatSensorIndex::VEHICLE_SPEED)));
+    const BitmaskIndexingInfo airflowIndexingInfo(BitmaskIndexingInfo::getForFloatSensor(
+        toInt(Obd2FloatSensorIndex::MAF_AIR_FLOW_RATE)));
+    if (speedIndexingInfo.mByteIndex == airflowIndexingInfo.mByteIndex) {
+        ASSERT_EQ(
+            speedIndexingInfo.mExpectedByteValue |
+            airflowIndexingInfo.mExpectedByteValue,
+            sensorBitmask[airflowIndexingInfo.mByteIndex]);
+    }
+    else {
+        ASSERT_EQ(
+            speedIndexingInfo.mExpectedByteValue,
+            sensorBitmask[speedIndexingInfo.mByteIndex]);
+        ASSERT_EQ(
+            airflowIndexingInfo.mExpectedByteValue,
+            sensorBitmask[airflowIndexingInfo.mByteIndex]);
+    }
+}
+
+// Test that one can set and retrieve a value for a vendor integer sensor.
+TEST(Obd2SensorStoreTest, setVendorIntegerSensor) {
+    const size_t sensorIndex = toInt(Obd2IntegerSensorIndex::LAST_SYSTEM_INDEX) + 2;
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setIntegerSensor(sensorIndex, 22);
+    const auto& integerSensors(sensorStore.getIntegerSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(22, integerSensors[sensorIndex]);
+    const BitmaskIndexingInfo indexingInfo(BitmaskIndexingInfo::getForIntegerSensor(
+        sensorIndex));
+    ASSERT_EQ(
+        indexingInfo.mExpectedByteValue,
+        sensorBitmask[indexingInfo.mByteIndex]);
+}
+
+// Test that one can set and retrieve a value for a vendor float sensor.
+TEST(Obd2SensorStoreTest, setVendorFloatSensor) {
+    const size_t sensorIndex = toInt(Obd2FloatSensorIndex::LAST_SYSTEM_INDEX) + 2;
+    Obd2SensorStore sensorStore(getSensorStore());
+    sensorStore.setFloatSensor(sensorIndex, 1.25f);
+    const auto& floatSensors(sensorStore.getFloatSensors());
+    const auto& sensorBitmask(sensorStore.getSensorsBitmask());
+    ASSERT_EQ(1.25f, floatSensors[sensorIndex]);
+    const BitmaskIndexingInfo indexingInfo(BitmaskIndexingInfo::getForFloatSensor(
+        sensorIndex));
+    ASSERT_EQ(
+        indexingInfo.mExpectedByteValue,
+        sensorBitmask[indexingInfo.mByteIndex]);
+}
+
+}  // namespace anonymous
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
diff --git a/vehicle/2.0/default/vehicle_hal_manager/Obd2SensorStore.cpp b/vehicle/2.0/default/vehicle_hal_manager/Obd2SensorStore.cpp
new file mode 100644
index 0000000..7be2662
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/Obd2SensorStore.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Obd2SensorStore.h"
+
+#include <vehicle_hal_manager/VehicleUtils.h>
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+Obd2SensorStore::BitmaskInVector::BitmaskInVector(size_t numBits)
+{
+    resize(numBits);
+}
+
+void Obd2SensorStore::BitmaskInVector::resize(size_t numBits) {
+    mStorage = std::vector<uint8_t>((numBits+7)/8, 0);
+}
+
+void Obd2SensorStore::BitmaskInVector::set(size_t index, bool value) {
+    const size_t byteIndex = index / 8;
+    const size_t bitIndex = index % 8;
+    const uint8_t byte = mStorage[byteIndex];
+    uint8_t newValue = value ? (byte | (1 << bitIndex)) :
+                               (byte & ~(1 << bitIndex));
+    mStorage[byteIndex] = newValue;
+}
+
+bool Obd2SensorStore::BitmaskInVector::get(size_t index) const {
+    const size_t byteIndex = index / 8;
+    const size_t bitIndex = index % 8;
+    const uint8_t byte = mStorage[byteIndex];
+    return (byte & (1 << bitIndex)) != 0;
+}
+
+const std::vector<uint8_t>& Obd2SensorStore::BitmaskInVector::getBitmask() const {
+    return mStorage;
+}
+
+Obd2SensorStore::Obd2SensorStore(size_t numVendorIntegerSensors,
+                                 size_t numVendorFloatSensors) {
+        // because the last index is valid *inclusive*
+        const size_t numSystemIntegerSensors = toInt(Obd2IntegerSensorIndex::LAST_SYSTEM_INDEX)+1;
+        const size_t numSystemFloatSensors = toInt(Obd2FloatSensorIndex::LAST_SYSTEM_INDEX)+1;
+        mIntegerSensors = std::vector<int32_t>(
+            numSystemIntegerSensors+numVendorIntegerSensors, 0);
+        mFloatSensors = std::vector<float>(
+            numSystemFloatSensors+numVendorFloatSensors, 0);
+        mSensorsBitmask.resize(mIntegerSensors.size()+mFloatSensors.size());
+}
+
+StatusCode Obd2SensorStore::setIntegerSensor(Obd2IntegerSensorIndex index,
+    int32_t value) {
+    return setIntegerSensor(toInt(index), value);
+}
+StatusCode Obd2SensorStore::setFloatSensor(Obd2FloatSensorIndex index,
+    float value) {
+    return setFloatSensor(toInt(index), value);
+}
+
+StatusCode Obd2SensorStore::setIntegerSensor(size_t index, int32_t value) {
+    mIntegerSensors[index] = value;
+    mSensorsBitmask.set(index, true);
+    return StatusCode::OK;
+}
+
+StatusCode Obd2SensorStore::setFloatSensor(size_t index, float value) {
+    mFloatSensors[index] = value;
+    mSensorsBitmask.set(index + mIntegerSensors.size(), true);
+    return StatusCode::OK;
+}
+
+const std::vector<int32_t>& Obd2SensorStore::getIntegerSensors() const {
+    return mIntegerSensors;
+}
+
+const std::vector<float>& Obd2SensorStore::getFloatSensors() const {
+    return mFloatSensors;
+}
+
+const std::vector<uint8_t>& Obd2SensorStore::getSensorsBitmask() const {
+    return mSensorsBitmask.getBitmask();
+}
+
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
diff --git a/vehicle/2.0/default/vehicle_hal_manager/Obd2SensorStore.h b/vehicle/2.0/default/vehicle_hal_manager/Obd2SensorStore.h
new file mode 100644
index 0000000..b18f5d4
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/Obd2SensorStore.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_vehicle_V2_0_Obd2SensorStore_H_
+#define android_hardware_vehicle_V2_0_Obd2SensorStore_H_
+
+#include <vector>
+
+#include <VehicleHal.h>
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+// This class wraps all the logic required to create an OBD2 frame.
+// It allows storing sensor values, setting appropriate bitmasks as needed,
+// and returning appropriately laid out storage of sensor values suitable
+// for being returned via a VehicleHal implementation.
+class Obd2SensorStore {
+public:
+    // Creates a sensor storage with a given number of vendor-specific sensors.
+    Obd2SensorStore(size_t numVendorIntegerSensors,
+                    size_t numVendorFloatSensors);
+
+    // Stores an integer-valued sensor.
+    StatusCode setIntegerSensor(Obd2IntegerSensorIndex index, int32_t value);
+    // Stores an integer-valued sensor.
+    StatusCode setIntegerSensor(size_t index, int32_t value);
+
+    // Stores a float-valued sensor.
+    StatusCode setFloatSensor(Obd2FloatSensorIndex index, float value);
+    // Stores a float-valued sensor.
+    StatusCode setFloatSensor(size_t index, float value);
+
+    // Returns a vector that contains all integer sensors stored.
+    const std::vector<int32_t>& getIntegerSensors() const;
+    // Returns a vector that contains all float sensors stored.
+    const std::vector<float>& getFloatSensors() const;
+    // Returns a vector that contains a bitmask for all stored sensors.
+    const std::vector<uint8_t>& getSensorsBitmask() const;
+
+private:
+    class BitmaskInVector {
+    public:
+        BitmaskInVector(size_t numBits = 0);
+        void resize(size_t numBits);
+        bool get(size_t index) const;
+        void set(size_t index, bool value);
+
+        const std::vector<uint8_t>& getBitmask() const;
+
+    private:
+        std::vector<uint8_t> mStorage;
+    };
+
+    std::vector<int32_t> mIntegerSensors;
+    std::vector<float> mFloatSensors;
+    BitmaskInVector mSensorsBitmask;
+};
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_vehicle_V2_0_Obd2SensorStore_H_
diff --git a/vehicle/2.0/types.hal b/vehicle/2.0/types.hal
index e1e4453..6609e5b 100644
--- a/vehicle/2.0/types.hal
+++ b/vehicle/2.0/types.hal
@@ -1042,7 +1042,7 @@
      * Property to report bootup reason for the current power on. This is a
      * static property that will not change for the whole duration until power
      * off. For example, even if user presses power on button after automatic
-     * power on with door unlock, bootup reason must stay with 
+     * power on with door unlock, bootup reason must stay with
      * VehicleApPowerBootupReason#USER_UNLOCK.
      *
      * int32Values[0] must be VehicleApPowerBootupReason.
@@ -1782,14 +1782,30 @@
      * This property uses COMPLEX data to send a snapshot of the current (live)
      * values of the OBD2 sensors provided by the vehicle.
      *
-     * Its contents are to be interpreted as follows:
+     * VehiclePropConfig
+     *   configArray[0] : number of vendor-specific integer-valued sensors
+     *                    that can be returned in a frame.
+     *   configArray[1] : number of vendor-specific float-valued sensors
+     *                    that can be returned in a frame.
+     *
+     * The values are to be interpreted as follows:
      * the indices defined in Obd2IntegerSensorIndex are to be used to
      * read from int32Values;
      * the indices defined in Obd2FloatSensorIndex are to be used to
      * read from floatValues.
+     * the elements of bytes are to be interpreted as a bitmask, such that
+     * the bits 0 thru the integer value of
+     * Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + the value of configArray[0]
+     * are 1 if the corresponding index is a valid sensor index whose value can
+     * be read in the returned int32Values vector, 0 otherwise.
+     * the bits Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX+1 thru
+     * Obd2FloatingSensorIndex.LAST_SYSTEM_INDEX + the value of configArray[1]
+     * are 1 if the corresponding index is a valid sensor index whose value
+     * can be read in the returned floatValues vector, 0 otherwise.
      *
      * For example, int32Values[0] corresponds to FUEL_SYSTEM_STATUS, and
-     * floatValues[0] corresponds to CALCULATED_ENGINE_LOAD.
+     * floatValues[0] corresponds to CALCULATED_ENGINE_LOAD, but that mapping
+     * is only valid if the corresponding bits in the bytes vector are set to 1.
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ
@@ -1807,17 +1823,33 @@
      * OBD2 sensors provided by the vehicle at the time that a diagnostic
      * troubleshooting code (DTC) was recorded by the vehicle.
      *
-     * Its contents are to be interpreted as follows:
+     * VehiclePropConfig
+     *   configArray[0] : number of vendor-specific integer-valued sensors
+     *                    that can be returned in a frame.
+     *   configArray[1] : number of vendor-specific float-valued sensors
+     *                    that can be returned in a frame.
+     *
+     * The values are to be interpreted as follows:
      * the indices defined in Obd2IntegerSensorIndex are to be used to
      * read from int32Values;
      * the indices defined in Obd2FloatSensorIndex are to be used to
      * read from floatValues;
+     * the elements of bytes are to be interpreted as a bitmask, such that
+     * the bits 0 thru the integer value of
+     * Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + the value of configArray[0]
+     * are 1 if the corresponding index is a valid sensor index whose value can
+     * be read in the returned int32Values vector, 0 otherwise.
+     * the bits Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX+1 thru
+     * Obd2FloatingSensorIndex.LAST_SYSTEM_INDEX + the value of configArray[1]
+     * are 1 if the corresponding index is a valid sensor index whose value
+     * can be read in the returned floatValues vector, 0 otherwise.
      * stringValue is the DTC that caused this freeze frame to be recorded.
      *
      * For example, int32Values[0] corresponds to FUEL_SYSTEM_STATUS, and
-     * floatValues[0] corresponds to CALCULATED_ENGINE_LOAD, and a possible
-     * valid stringValue is "P0176" to indicate a malfunction of the fuel
-     * composition sensor circuit.
+     * floatValues[0] corresponds to CALCULATED_ENGINE_LOAD, but that mapping
+     * is only valid if the corresponding bits in the bytes vector are set to 1,
+     * and a possible valid stringValue is "P0176" to indicate a malfunction
+     * of the fuel composition sensor circuit.
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ
diff --git a/vr/1.0/default/Android.bp b/vr/1.0/default/Android.bp
index d100570..da8a754 100644
--- a/vr/1.0/default/Android.bp
+++ b/vr/1.0/default/Android.bp
@@ -15,3 +15,20 @@
         "android.hardware.vr@1.0",
     ],
 }
+
+cc_binary {
+    relative_install_path: "hw",
+    name: "android.hardware.vr@1.0-service",
+    init_rc: ["android.hardware.vr@1.0-service.rc"],
+    srcs: ["service.cpp"],
+    shared_libs: [
+        "liblog",
+        "libdl",
+        "libutils",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "android.hardware.vr@1.0",
+    ],
+}
diff --git a/vr/1.0/vts/functional/vr_hidl_hal_test.cpp b/vr/1.0/vts/functional/vr_hidl_hal_test.cpp
index 7e85337..29888fd 100644
--- a/vr/1.0/vts/functional/vr_hidl_hal_test.cpp
+++ b/vr/1.0/vts/functional/vr_hidl_hal_test.cpp
@@ -34,7 +34,6 @@
   void SetUp() override {
     vr = IVr::getService(VR_SERVICE_NAME);
     ASSERT_NE(vr, nullptr);
-    ASSERT_TRUE(!vr->isRemote());
   }
 
   void TearDown() override {}
diff --git a/wifi/1.0/IWifiNanIfaceEventCallback.hal b/wifi/1.0/IWifiNanIfaceEventCallback.hal
index 906d673..cb4b043 100644
--- a/wifi/1.0/IWifiNanIfaceEventCallback.hal
+++ b/wifi/1.0/IWifiNanIfaceEventCallback.hal
@@ -162,8 +162,10 @@
    *        |NanStatusType.INTERNAL_FAILURE|
    *        |NanStatusType.PROTOCOL_FAILURE|
    *        |NanStatusType.INVALID_PEER_ID|
+   * @param ndpInstanceId ID of the new data path being negotiated (on successful status).
    */
-  oneway notifyInitiateDataPathResponse(CommandIdShort id, WifiNanStatus status);
+  oneway notifyInitiateDataPathResponse(CommandIdShort id, WifiNanStatus status,
+        uint32_t ndpInstanceId );
 
   /**
    * Callback invoked in response to a respond to data path indication request
@@ -176,10 +178,8 @@
    *        |NanStatusType.INTERNAL_FAILURE|
    *        |NanStatusType.PROTOCOL_FAILURE|
    *        |NanStatusType.INVALID_NDP_ID|
-   * @param ndpInstanceId ID of the new data path being negotiated (on successful status).
    */
-  oneway notifyRespondToDataPathIndicationResponse(CommandIdShort id, WifiNanStatus status,
-                                                   uint32_t ndpInstanceId);
+  oneway notifyRespondToDataPathIndicationResponse(CommandIdShort id, WifiNanStatus status);
 
   /**
    * Callback invoked in response to a terminate data path request |terminateDataPathRequest|.
diff --git a/wifi/1.0/IWifiStaIface.hal b/wifi/1.0/IWifiStaIface.hal
index 2c72ead..96dc54a 100644
--- a/wifi/1.0/IWifiStaIface.hal
+++ b/wifi/1.0/IWifiStaIface.hal
@@ -438,6 +438,19 @@
   stopSendingKeepAlivePackets(CommandId cmdId) generates (WifiStatus status);
 
   /**
+   * Set the MAC OUI during scanning.
+   * An OUI {Organizationally Unique Identifier} is a 24-bit number that
+   * uniquely identifies a vendor or manufacturer.
+   *
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+   *         |WifiStatusCode.ERROR_UNKNOWN|
+   */
+  setScanningMacOui(uint8_t[3] oui) generates (WifiStatus status);
+
+  /**
    * API to start packet fate monitoring.
    * - Once started, monitoring must remain active until HAL is stopped or the
    *   chip is reconfigured.
diff --git a/wifi/1.0/default/hidl_struct_util.cpp b/wifi/1.0/default/hidl_struct_util.cpp
index 37fcfea..7464b81 100644
--- a/wifi/1.0/default/hidl_struct_util.cpp
+++ b/wifi/1.0/default/hidl_struct_util.cpp
@@ -759,17 +759,17 @@
     const NanEnableRequest& hidl_request,
     legacy_hal::NanEnableRequest* legacy_request) {
   if (!legacy_request) {
+    LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: null legacy_request";
     return false;
   }
   memset(legacy_request, 0, sizeof(legacy_hal::NanEnableRequest));
 
-  // TODO: b/34059183 tracks missing configurations in legacy HAL or uknown defaults
   legacy_request->config_2dot4g_support = 1;
   legacy_request->support_2dot4g_val = hidl_request.operateInBand[
         (size_t) NanBandIndex::NAN_BAND_24GHZ];
   legacy_request->config_support_5g = 1;
   legacy_request->support_5g_val = hidl_request.operateInBand[(size_t) NanBandIndex::NAN_BAND_5GHZ];
-  legacy_request->config_hop_count_limit = 0; // TODO: don't know default yet
+  legacy_request->config_hop_count_limit = 1;
   legacy_request->hop_count_limit_val = hidl_request.hopCountMax;
   legacy_request->master_pref = hidl_request.configParams.masterPref;
   legacy_request->discovery_indication_cfg = 0;
@@ -781,11 +781,12 @@
         hidl_request.configParams.disableJoinedClusterIndication ? 0x4 : 0x0;
   legacy_request->config_sid_beacon = 1;
   if (hidl_request.configParams.numberOfServiceIdsInBeacon > 127) {
+    LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: numberOfServiceIdsInBeacon > 127";
     return false;
   }
   legacy_request->sid_beacon_val = (hidl_request.configParams.includeServiceIdsInBeacon ? 0x1 : 0x0)
         | (hidl_request.configParams.numberOfServiceIdsInBeacon << 1);
-  legacy_request->config_rssi_window_size = 0; // TODO: don't know default yet
+  legacy_request->config_rssi_window_size = 1;
   legacy_request->rssi_window_size_val = hidl_request.configParams.rssiWindowSize;
   legacy_request->config_disc_mac_addr_randomization = 1;
   legacy_request->disc_mac_addr_rand_interval_sec =
@@ -793,19 +794,23 @@
   legacy_request->config_responder_auto_response = 1;
   legacy_request->ranging_auto_response_cfg = hidl_request.configParams.acceptRangingRequests ?
        legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
-  legacy_request->config_2dot4g_rssi_close = 0; // TODO: don't know default yet
+  legacy_request->config_2dot4g_rssi_close = 1;
+  if (hidl_request.configParams.bandSpecificConfig.size() != 2) {
+    LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: bandSpecificConfig.size() != 2";
+    return false;
+  }
   legacy_request->rssi_close_2dot4g_val =
         hidl_request.configParams.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiClose;
-  legacy_request->config_2dot4g_rssi_middle = 0; // TODO: don't know default yet
+  legacy_request->config_2dot4g_rssi_middle = 1;
   legacy_request->rssi_middle_2dot4g_val =
         hidl_request.configParams.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiMiddle;
-  legacy_request->config_2dot4g_rssi_proximity = 0; // TODO: don't know default yet
+  legacy_request->config_2dot4g_rssi_proximity = 1;
   legacy_request->rssi_proximity_2dot4g_val =
         hidl_request.configParams.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiProximity;
-  legacy_request->config_scan_params = 0; // TODO: don't know default yet
+  legacy_request->config_scan_params = 1;
   legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
         hidl_request.configParams.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_24GHZ].dwellTimeMs;
@@ -816,15 +821,15 @@
         .bandSpecificConfig[(size_t) NanBandIndex::NAN_BAND_24GHZ].validDiscoveryWindowIntervalVal;
   legacy_request->config_dw.dw_2dot4g_interval_val = hidl_request.configParams
         .bandSpecificConfig[(size_t) NanBandIndex::NAN_BAND_24GHZ].discoveryWindowIntervalVal;
-  legacy_request->config_5g_rssi_close = 0; // TODO: don't know default yet
+  legacy_request->config_5g_rssi_close = 1;
   legacy_request->rssi_close_5g_val =
         hidl_request.configParams.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiClose;
-  legacy_request->config_5g_rssi_middle = 0; // TODO: don't know default yet
+  legacy_request->config_5g_rssi_middle = 1;
   legacy_request->rssi_middle_5g_val =
         hidl_request.configParams.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiMiddle;
-  legacy_request->config_5g_rssi_close_proximity = 0; // TODO: don't know default yet
+  legacy_request->config_5g_rssi_close_proximity = 1;
   legacy_request->rssi_close_proximity_5g_val =
         hidl_request.configParams.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiProximity;
@@ -885,6 +890,7 @@
     const NanPublishRequest& hidl_request,
     legacy_hal::NanPublishRequest* legacy_request) {
   if (!legacy_request) {
+    LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: null legacy_request";
     return false;
   }
   memset(legacy_request, 0, sizeof(legacy_hal::NanPublishRequest));
@@ -895,14 +901,16 @@
   legacy_request->publish_count = hidl_request.baseConfigs.discoveryCount;
   legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size();
   if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+    LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: service_name_len too large";
     return false;
   }
-  memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.c_str(),
+  memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
         legacy_request->service_name_len);
   legacy_request->publish_match_indicator =
         (legacy_hal::NanMatchAlg) hidl_request.baseConfigs.discoveryMatchIndicator;
   legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
   if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+    LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: service_specific_info_len too large";
     return false;
   }
   memcpy(legacy_request->service_specific_info,
@@ -910,6 +918,7 @@
         legacy_request->service_specific_info_len);
   legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size();
   if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+    LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: rx_match_filter_len too large";
     return false;
   }
   memcpy(legacy_request->rx_match_filter,
@@ -917,6 +926,7 @@
         legacy_request->rx_match_filter_len);
   legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size();
   if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+    LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: tx_match_filter_len too large";
     return false;
   }
   memcpy(legacy_request->tx_match_filter,
@@ -933,6 +943,7 @@
   legacy_request->cipher_type = hidl_request.baseConfigs.supportedCipherTypes;
   legacy_request->pmk_len = hidl_request.baseConfigs.pmk.size();
   if (legacy_request->pmk_len > NAN_PMK_INFO_LEN) {
+    LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: pmk_len too large";
     return false;
   }
   memcpy(legacy_request->pmk,
@@ -957,6 +968,7 @@
     const NanSubscribeRequest& hidl_request,
     legacy_hal::NanSubscribeRequest* legacy_request) {
   if (!legacy_request) {
+    LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: legacy_request is null";
     return false;
   }
   memset(legacy_request, 0, sizeof(legacy_hal::NanSubscribeRequest));
@@ -967,14 +979,16 @@
   legacy_request->subscribe_count = hidl_request.baseConfigs.discoveryCount;
   legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size();
   if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+    LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: service_name_len too large";
     return false;
   }
-  memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.c_str(),
+  memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
         legacy_request->service_name_len);
   legacy_request->subscribe_match_indicator =
         (legacy_hal::NanMatchAlg) hidl_request.baseConfigs.discoveryMatchIndicator;
   legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
   if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+    LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: service_specific_info_len too large";
     return false;
   }
   memcpy(legacy_request->service_specific_info,
@@ -982,6 +996,7 @@
         legacy_request->service_specific_info_len);
   legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size();
   if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+    LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: rx_match_filter_len too large";
     return false;
   }
   memcpy(legacy_request->rx_match_filter,
@@ -989,6 +1004,7 @@
         legacy_request->rx_match_filter_len);
   legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size();
   if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+    LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: tx_match_filter_len too large";
     return false;
   }
   memcpy(legacy_request->tx_match_filter,
@@ -1005,6 +1021,7 @@
   legacy_request->cipher_type = hidl_request.baseConfigs.supportedCipherTypes;
   legacy_request->pmk_len = hidl_request.baseConfigs.pmk.size();
   if (legacy_request->pmk_len > NAN_PMK_INFO_LEN) {
+    LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: pmk_len too large";
     return false;
   }
   memcpy(legacy_request->pmk,
@@ -1029,6 +1046,7 @@
         legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
   legacy_request->num_intf_addr_present = hidl_request.intfAddr.size();
   if (legacy_request->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) {
+    LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: num_intf_addr_present - too many";
     return false;
   }
   for (int i = 0; i < legacy_request->num_intf_addr_present; i++) {
@@ -1042,6 +1060,7 @@
     const NanTransmitFollowupRequest& hidl_request,
     legacy_hal::NanTransmitFollowupRequest* legacy_request) {
   if (!legacy_request) {
+    LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: legacy_request is null";
     return false;
   }
   memset(legacy_request, 0, sizeof(legacy_hal::NanTransmitFollowupRequest));
@@ -1055,6 +1074,7 @@
         legacy_hal::NAN_TRANSMIT_IN_DW : legacy_hal::NAN_TRANSMIT_IN_FAW;
   legacy_request->service_specific_info_len = hidl_request.message.size();
   if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+    LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: service_specific_info_len too large";
     return false;
   }
   memcpy(legacy_request->service_specific_info,
@@ -1069,6 +1089,7 @@
     const NanConfigRequest& hidl_request,
     legacy_hal::NanConfigRequest* legacy_request) {
   if (!legacy_request) {
+    LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: legacy_request is null";
     return false;
   }
   memset(legacy_request, 0, sizeof(legacy_hal::NanConfigRequest));
@@ -1084,11 +1105,12 @@
         hidl_request.disableJoinedClusterIndication ? 0x4 : 0x0;
   legacy_request->config_sid_beacon = 1;
   if (hidl_request.numberOfServiceIdsInBeacon > 127) {
+    LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: numberOfServiceIdsInBeacon > 127";
     return false;
   }
   legacy_request->sid_beacon = (hidl_request.includeServiceIdsInBeacon ? 0x1 : 0x0)
         | (hidl_request.numberOfServiceIdsInBeacon << 1);
-  legacy_request->config_rssi_window_size = 0; // TODO: don't know default yet
+  legacy_request->config_rssi_window_size = 1;
   legacy_request->rssi_window_size_val = hidl_request.rssiWindowSize;
   legacy_request->config_disc_mac_addr_randomization = 1;
   legacy_request->disc_mac_addr_rand_interval_sec =
@@ -1097,20 +1119,20 @@
   legacy_request->ranging_auto_response_cfg = hidl_request.acceptRangingRequests ?
        legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
   /* TODO : missing
-  legacy_request->config_2dot4g_rssi_close = 0; // TODO: don't know default yet
+  legacy_request->config_2dot4g_rssi_close = 1;
   legacy_request->rssi_close_2dot4g_val =
         hidl_request.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiClose;
-  legacy_request->config_2dot4g_rssi_middle = 0; // TODO: don't know default yet
+  legacy_request->config_2dot4g_rssi_middle = 1;
   legacy_request->rssi_middle_2dot4g_val =
         hidl_request.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiMiddle;
-  legacy_request->config_2dot4g_rssi_proximity = 0; // TODO: don't know default yet
+  legacy_request->config_2dot4g_rssi_proximity = 1;
   legacy_request->rssi_proximity_2dot4g_val =
         hidl_request.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiProximity;
   */
-  legacy_request->config_scan_params = 0; // TODO: don't know default yet
+  legacy_request->config_scan_params = 1;
   legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
         hidl_request.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_24GHZ].dwellTimeMs;
@@ -1122,16 +1144,16 @@
   legacy_request->config_dw.dw_2dot4g_interval_val = hidl_request
         .bandSpecificConfig[(size_t) NanBandIndex::NAN_BAND_24GHZ].discoveryWindowIntervalVal;
   /* TODO: missing
-  legacy_request->config_5g_rssi_close = 0; // TODO: don't know default yet
+  legacy_request->config_5g_rssi_close = 1;
   legacy_request->rssi_close_5g_val =
         hidl_request.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiClose;
-  legacy_request->config_5g_rssi_middle = 0; // TODO: don't know default yet
+  legacy_request->config_5g_rssi_middle = 1;
   legacy_request->rssi_middle_5g_val =
         hidl_request.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiMiddle;
   */
-  legacy_request->config_5g_rssi_close_proximity = 0; // TODO: don't know default yet
+  legacy_request->config_5g_rssi_close_proximity = 1;
   legacy_request->rssi_close_proximity_5g_val =
         hidl_request.bandSpecificConfig[
             (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiProximity;
@@ -1159,6 +1181,7 @@
     const NanBeaconSdfPayloadRequest& hidl_request,
     legacy_hal::NanBeaconSdfPayloadRequest* legacy_request) {
   if (!legacy_request) {
+    LOG(ERROR) << "convertHidlNanBeaconSdfPayloadRequestToLegacy: legacy_request is null";
     return false;
   }
   memset(legacy_request, 0, sizeof(legacy_hal::NanBeaconSdfPayloadRequest));
@@ -1170,6 +1193,7 @@
   legacy_request->vsa.vendor_oui = hidl_request.vendorOui;
   legacy_request->vsa.vsa_len = hidl_request.vsa.size();
   if (legacy_request->vsa.vsa_len > NAN_MAX_VSA_DATA_LEN) {
+    LOG(ERROR) << "convertHidlNanBeaconSdfPayloadRequestToLegacy: vsa_len too long";
     return false;
   }
   memcpy(legacy_request->vsa.vsa, hidl_request.vsa.data(), legacy_request->vsa.vsa_len);
@@ -1181,6 +1205,7 @@
     const NanInitiateDataPathRequest& hidl_request,
     legacy_hal::NanDataPathInitiatorRequest* legacy_request) {
   if (!legacy_request) {
+    LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: legacy_request is null";
     return false;
   }
   memset(legacy_request, 0, sizeof(legacy_hal::NanDataPathInitiatorRequest));
@@ -1195,6 +1220,7 @@
         legacy_hal::NAN_DP_CONFIG_SECURITY : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
   legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
   if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+    LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: ndp_app_info_len to large";
     return false;
   }
   memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
@@ -1213,6 +1239,7 @@
     const NanRespondToDataPathIndicationRequest& hidl_request,
     legacy_hal::NanDataPathIndicationResponse* legacy_request) {
   if (!legacy_request) {
+    LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: legacy_request is null";
     return false;
   }
   memset(legacy_request, 0, sizeof(legacy_hal::NanDataPathIndicationResponse));
@@ -1225,6 +1252,7 @@
         legacy_hal::NAN_DP_CONFIG_SECURITY : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
   legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
   if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+    LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: ndp_app_info_len too large";
     return false;
   }
   memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
@@ -1232,6 +1260,7 @@
   legacy_request->cipher_type = hidl_request.supportedCipherTypes;
   legacy_request->pmk_len = hidl_request.pmk.size();
   if (legacy_request->pmk_len > NAN_PMK_INFO_LEN) {
+    LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: pmk_len too large";
     return false;
   }
   memcpy(legacy_request->pmk, hidl_request.pmk.data(), legacy_request->pmk_len);
@@ -1243,6 +1272,7 @@
     const legacy_hal::NanResponseMsg& legacy_response,
     WifiNanStatus* wifiNanStatus) {
   if (!wifiNanStatus) {
+    LOG(ERROR) << "convertLegacyNanResponseHeaderToHidl: wifiNanStatus is null";
     return false;
   }
   wifiNanStatus->status = convertLegacyNanStatusTypeToHidl(legacy_response.status);
@@ -1255,6 +1285,7 @@
     const legacy_hal::NanCapabilities& legacy_response,
     NanCapabilities* hidl_response) {
   if (!hidl_response) {
+    LOG(ERROR) << "convertLegacyNanCapabilitiesResponseToHidl: hidl_response is null";
     return false;
   }
   hidl_response->maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters;
@@ -1280,6 +1311,7 @@
     const legacy_hal::NanMatchInd& legacy_ind,
     NanMatchInd* hidl_ind) {
   if (!hidl_ind) {
+    LOG(ERROR) << "convertLegacyNanMatchIndToHidl: hidl_ind is null";
     return false;
   }
   hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
@@ -1307,6 +1339,7 @@
     const legacy_hal::NanFollowupInd& legacy_ind,
     NanFollowupReceivedInd* hidl_ind) {
   if (!hidl_ind) {
+    LOG(ERROR) << "convertLegacyNanFollowupIndToHidl: hidl_ind is null";
     return false;
   }
   hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
@@ -1323,6 +1356,7 @@
     const legacy_hal::NanBeaconSdfPayloadInd& legacy_ind,
     NanBeaconSdfPayloadInd* hidl_ind) {
   if (!hidl_ind) {
+    LOG(ERROR) << "convertLegacyNanBeaconSdfPayloadIndToHidl: hidl_ind is null";
     return false;
   }
   hidl_ind->addr = hidl_array<uint8_t, 6>(legacy_ind.addr);
@@ -1342,6 +1376,7 @@
     const legacy_hal::NanDataPathRequestInd& legacy_ind,
     NanDataPathRequestInd* hidl_ind) {
   if (!hidl_ind) {
+    LOG(ERROR) << "convertLegacyNanDataPathRequestIndToHidl: hidl_ind is null";
     return false;
   }
   hidl_ind->discoverySessionId = legacy_ind.service_instance_id;
@@ -1359,6 +1394,7 @@
     const legacy_hal::NanDataPathConfirmInd& legacy_ind,
     NanDataPathConfirmInd* hidl_ind) {
   if (!hidl_ind) {
+    LOG(ERROR) << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null";
     return false;
   }
   hidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id;
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
index e4eddcd..b0b0f96 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -685,6 +685,12 @@
       cmd_id, wlan_interface_handle_);
 }
 
+wifi_error WifiLegacyHal::setScanningMacOui(const std::array<uint8_t, 3>& oui) {
+  std::vector<uint8_t> oui_internal(oui.data(), oui.data() + oui.size());
+  return global_func_table_.wifi_set_scanning_mac_oui(wlan_interface_handle_,
+                                                      oui_internal.data());
+}
+
 std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet() {
   uint32_t supported_features;
   wifi_error status = global_func_table_.wifi_get_logger_supported_feature_set(
diff --git a/wifi/1.0/default/wifi_legacy_hal.h b/wifi/1.0/default/wifi_legacy_hal.h
index 1ab74b7..dce4ed4 100644
--- a/wifi/1.0/default/wifi_legacy_hal.h
+++ b/wifi/1.0/default/wifi_legacy_hal.h
@@ -192,6 +192,7 @@
       const std::array<uint8_t, 6>& dst_address,
       uint32_t period_in_ms);
   wifi_error stopSendingOffloadedPacket(uint32_t cmd_id);
+  wifi_error setScanningMacOui(const std::array<uint8_t, 3>& oui);
   // Logger/debug functions.
   std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet();
   wifi_error startPktFateMonitoring();
diff --git a/wifi/1.0/default/wifi_nan_iface.cpp b/wifi/1.0/default/wifi_nan_iface.cpp
index 5ac6fa8..333fac7 100644
--- a/wifi/1.0/default/wifi_nan_iface.cpp
+++ b/wifi/1.0/default/wifi_nan_iface.cpp
@@ -60,6 +60,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_RESPONSE_DISABLED: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -67,6 +68,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_RESPONSE_PUBLISH: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -75,6 +77,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -82,6 +85,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -89,6 +93,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_RESPONSE_SUBSCRIBE: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -97,6 +102,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -104,6 +110,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_RESPONSE_CONFIG: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -111,6 +118,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
      }
     case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -118,6 +126,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
      }
     case legacy_hal::NAN_GET_CAPABILITIES: {
         NanCapabilities hidl_struct;
@@ -132,6 +141,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_DP_INTERFACE_CREATE: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -139,6 +149,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_DP_INTERFACE_DELETE: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
@@ -146,18 +157,20 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_DP_INITIATOR_RESPONSE: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
-          if (!callback->notifyInitiateDataPathResponse(id, wifiNanStatus).isOk()) {
+          if (!callback->notifyInitiateDataPathResponse(id, wifiNanStatus,
+                msg.body.data_request_response.ndp_instance_id).isOk()) {
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_DP_RESPONDER_RESPONSE: {
         for (const auto& callback : shared_ptr_this->event_callbacks_) {
-          if (!callback->notifyRespondToDataPathIndicationResponse(id, wifiNanStatus,
-                    msg.body.data_request_response.ndp_instance_id).isOk()) {
+          if (!callback->notifyRespondToDataPathIndicationResponse(id, wifiNanStatus).isOk()) {
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
@@ -168,6 +181,7 @@
             LOG(ERROR) << "Failed to invoke the callback";
           }
         }
+        break;
     }
     case legacy_hal::NAN_RESPONSE_TCA:
         /* fall through */
diff --git a/wifi/1.0/default/wifi_sta_iface.cpp b/wifi/1.0/default/wifi_sta_iface.cpp
index be2fe37..6cc41db 100644
--- a/wifi/1.0/default/wifi_sta_iface.cpp
+++ b/wifi/1.0/default/wifi_sta_iface.cpp
@@ -250,6 +250,15 @@
                          cmd_id);
 }
 
+Return<void> WifiStaIface::setScanningMacOui(
+    const hidl_array<uint8_t, 3>& oui, setScanningMacOui_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                         &WifiStaIface::setScanningMacOuiInternal,
+                         hidl_status_cb,
+                         oui);
+}
+
 Return<void> WifiStaIface::startDebugPacketFateMonitoring(
     startDebugPacketFateMonitoring_cb hidl_status_cb) {
   return validateAndCall(this,
@@ -553,6 +562,12 @@
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
+WifiStatus WifiStaIface::setScanningMacOuiInternal(const std::array<uint8_t, 3>& oui) {
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->setScanningMacOui(oui);
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
 WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
   legacy_hal::wifi_error legacy_status =
       legacy_hal_.lock()->startPktFateMonitoring();
diff --git a/wifi/1.0/default/wifi_sta_iface.h b/wifi/1.0/default/wifi_sta_iface.h
index ca79c5b..bc2d75f 100644
--- a/wifi/1.0/default/wifi_sta_iface.h
+++ b/wifi/1.0/default/wifi_sta_iface.h
@@ -95,6 +95,8 @@
       startSendingKeepAlivePackets_cb hidl_status_cb) override;
   Return<void> stopSendingKeepAlivePackets(
       uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) override;
+  Return<void> setScanningMacOui(const hidl_array<uint8_t, 3>& oui,
+                                 setScanningMacOui_cb hidl_status_cb) override;
   Return<void> startDebugPacketFateMonitoring(
       startDebugPacketFateMonitoring_cb hidl_status_cb) override;
   Return<void> getDebugTxPacketFates(
@@ -140,6 +142,7 @@
       const std::array<uint8_t, 6>& dst_address,
       uint32_t period_in_ms);
   WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id);
+  WifiStatus setScanningMacOuiInternal(const std::array<uint8_t, 3>& oui);
   WifiStatus startDebugPacketFateMonitoringInternal();
   std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>
   getDebugTxPacketFatesInternal();
diff --git a/wifi/1.0/types.hal b/wifi/1.0/types.hal
index bb00114..1ec1357 100644
--- a/wifi/1.0/types.hal
+++ b/wifi/1.0/types.hal
@@ -750,19 +750,19 @@
    * Frequency in MHz to of the discovery channel in the specified band. Indexed by |NanBandIndex|.
    */
   bool validDiscoveryChannelVal;
-  vec<WifiChannelInMhz> discoveryChannelMhzVal;
+  WifiChannelInMhz[2] discoveryChannelMhzVal;
   /**
    * Specifies whether sync/discovery beacons are transmitted in the specified band. Indexed by
    * |NanBandIndex|.
    */
   bool validUseBeaconsInBandVal;
-  vec<bool> useBeaconsInBandVal;
+  bool[2] useBeaconsInBandVal;
   /**
    * Specified whether SDF (service discovery frames) are transmitted in the specified band. Indexed
    * by |NanBandIndex|.
    */
   bool validUseSdfInBandVal;
-  vec<bool> useSdfInBandVal;
+  bool[2] useSdfInBandVal;
 };
 
 /**
@@ -816,7 +816,7 @@
   /**
    * Additional configuration provided per band: indexed by |NanBandIndex|.
    */
-  vec<NanBandSpecificConfig> bandSpecificConfig;
+  NanBandSpecificConfig[2] bandSpecificConfig;
 };
 
 /**
@@ -826,7 +826,7 @@
   /**
    * Enable operation in a specific band: indexed by |NanBandIndex|.
    */
-  vec<bool> operateInBand;
+  bool[2] operateInBand;
   /**
    * Specify extent of cluster by specifying the max hop count.
    */
@@ -888,7 +888,7 @@
    * UTF-8 encoded string identifying the service.
    * Max length: |NanCapabilities.maxServiceNameLen|.
    */
-  string serviceName;
+  vec<uint8_t> serviceName;
   /**
    * Specifies the matching indication to host: once, continuous, or never.
    */