Merge "Camera: add interface to evict obsolete buffer caches" into oc-dev
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index 9a4efae..d699f21 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -23,9 +23,8 @@
 #include <hardware/bluetooth.h>
 #include <utils/Log.h>
 
+#include <VtsHalHidlTargetCallbackBase.h>
 #include <VtsHalHidlTargetTestBase.h>
-#include <condition_variable>
-#include <mutex>
 #include <queue>
 
 using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
@@ -92,6 +91,11 @@
 #define ACL_BROADCAST_ACTIVE_SLAVE (0x1 << 4)
 #define ACL_PACKET_BOUNDARY_COMPLETE (0x3 << 6)
 
+constexpr char kCallbackNameAclEventReceived[] = "aclDataReceived";
+constexpr char kCallbackNameHciEventReceived[] = "hciEventReceived";
+constexpr char kCallbackNameInitializationComplete[] = "initializationComplete";
+constexpr char kCallbackNameScoEventReceived[] = "scoDataReceived";
+
 class ThroughputLogger {
  public:
   ThroughputLogger(std::string task)
@@ -121,7 +125,8 @@
  public:
   virtual void SetUp() override {
     // currently test passthrough mode only
-    bluetooth = ::testing::VtsHalHidlTargetTestBase::getService<IBluetoothHci>();
+    bluetooth =
+        ::testing::VtsHalHidlTargetTestBase::getService<IBluetoothHci>();
     ASSERT_NE(bluetooth, nullptr);
     ALOGI("%s: getService() for bluetooth is %s", __func__,
           bluetooth->isRemote() ? "remote" : "local");
@@ -135,10 +140,6 @@
     max_sco_data_packets = 0;
 
     initialized = false;
-    initialized_count = 0;
-    event_count = 0;
-    acl_count = 0;
-    sco_count = 0;
     event_cb_count = 0;
     acl_cb_count = 0;
     sco_cb_count = 0;
@@ -146,7 +147,18 @@
     ASSERT_EQ(initialized, false);
     bluetooth->initialize(bluetooth_cb);
 
-    wait_for_init_callback();
+    bluetooth_cb->SetWaitTimeout(kCallbackNameInitializationComplete,
+                                 WAIT_FOR_INIT_TIMEOUT);
+    bluetooth_cb->SetWaitTimeout(kCallbackNameHciEventReceived,
+                                 WAIT_FOR_HCI_EVENT_TIMEOUT);
+    bluetooth_cb->SetWaitTimeout(kCallbackNameAclEventReceived,
+                                 WAIT_FOR_ACL_DATA_TIMEOUT);
+    bluetooth_cb->SetWaitTimeout(kCallbackNameScoEventReceived,
+                                 WAIT_FOR_SCO_DATA_TIMEOUT);
+
+    EXPECT_TRUE(
+        bluetooth_cb->WaitForCallback(kCallbackNameInitializationComplete)
+            .no_timeout);
 
     ASSERT_EQ(initialized, true);
   }
@@ -171,82 +183,10 @@
   void wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
   int wait_for_completed_packets_event(uint16_t handle);
 
-  // Inform the test about the initialization callback
-  inline void notify_initialized() {
-    std::unique_lock<std::mutex> lock(initialized_mutex);
-    initialized_count++;
-    initialized_condition.notify_one();
-  }
-
-  // Test code calls this function to wait for the init callback
-  inline void wait_for_init_callback() {
-    std::unique_lock<std::mutex> lock(initialized_mutex);
-
-    auto start_time = std::chrono::steady_clock::now();
-    while (initialized_count == 0)
-      if (initialized_condition.wait_until(lock,
-                                     start_time + WAIT_FOR_INIT_TIMEOUT) ==
-          std::cv_status::timeout)
-        return;
-    initialized_count--;
-  }
-
-  // Inform the test about an event callback
-  inline void notify_event_received() {
-    std::unique_lock<std::mutex> lock(event_mutex);
-    event_count++;
-    event_condition.notify_one();
-  }
-
-  // Test code calls this function to wait for an event callback
-  inline void wait_for_event() {
-    std::unique_lock<std::mutex> lock(event_mutex);
-
-    auto start_time = std::chrono::steady_clock::now();
-    while (event_count == 0)
-      if (event_condition.wait_until(lock,
-                                     start_time + WAIT_FOR_HCI_EVENT_TIMEOUT) ==
-          std::cv_status::timeout)
-        return;
-    event_count--;
-  }
-
-  // Inform the test about an acl data callback
-  inline void notify_acl_data_received() {
-    std::unique_lock<std::mutex> lock(acl_mutex);
-    acl_count++;
-    acl_condition.notify_one();
-  }
-
-  // Test code calls this function to wait for an acl data callback
-  inline void wait_for_acl() {
-    std::unique_lock<std::mutex> lock(acl_mutex);
-
-    while (acl_count == 0)
-      acl_condition.wait_until(
-          lock, std::chrono::steady_clock::now() + WAIT_FOR_ACL_DATA_TIMEOUT);
-    acl_count--;
-  }
-
-  // Inform the test about a sco data callback
-  inline void notify_sco_data_received() {
-    std::unique_lock<std::mutex> lock(sco_mutex);
-    sco_count++;
-    sco_condition.notify_one();
-  }
-
-  // Test code calls this function to wait for a sco data callback
-  inline void wait_for_sco() {
-    std::unique_lock<std::mutex> lock(sco_mutex);
-
-    while (sco_count == 0)
-      sco_condition.wait_until(
-          lock, std::chrono::steady_clock::now() + WAIT_FOR_SCO_DATA_TIMEOUT);
-    sco_count--;
-  }
-
   // A simple test implementation of BluetoothHciCallbacks.
-  class BluetoothHciCallbacks : public IBluetoothHciCallbacks {
+  class BluetoothHciCallbacks
+      : public ::testing::VtsHalHidlTargetCallbackBase<BluetoothHidlTest>,
+        public IBluetoothHciCallbacks {
     BluetoothHidlTest& parent_;
 
    public:
@@ -256,7 +196,7 @@
 
     Return<void> initializationComplete(Status status) override {
       parent_.initialized = (status == Status::SUCCESS);
-      parent_.notify_initialized();
+      NotifyFromCallback(kCallbackNameInitializationComplete);
       ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
       return Void();
     };
@@ -265,7 +205,7 @@
         const ::android::hardware::hidl_vec<uint8_t>& event) override {
       parent_.event_cb_count++;
       parent_.event_queue.push(event);
-      parent_.notify_event_received();
+      NotifyFromCallback(kCallbackNameHciEventReceived);
       ALOGV("Event received (length = %d)", static_cast<int>(event.size()));
       return Void();
     };
@@ -274,7 +214,7 @@
         const ::android::hardware::hidl_vec<uint8_t>& data) override {
       parent_.acl_cb_count++;
       parent_.acl_queue.push(data);
-      parent_.notify_acl_data_received();
+      NotifyFromCallback(kCallbackNameAclEventReceived);
       return Void();
     };
 
@@ -282,13 +222,13 @@
         const ::android::hardware::hidl_vec<uint8_t>& data) override {
       parent_.sco_cb_count++;
       parent_.sco_queue.push(data);
-      parent_.notify_sco_data_received();
+      NotifyFromCallback(kCallbackNameScoEventReceived);
       return Void();
     };
   };
 
   sp<IBluetoothHci> bluetooth;
-  sp<IBluetoothHciCallbacks> bluetooth_cb;
+  sp<BluetoothHciCallbacks> bluetooth_cb;
   std::queue<hidl_vec<uint8_t>> event_queue;
   std::queue<hidl_vec<uint8_t>> acl_queue;
   std::queue<hidl_vec<uint8_t>> sco_queue;
@@ -303,20 +243,6 @@
   int max_sco_data_packet_length;
   int max_acl_data_packets;
   int max_sco_data_packets;
-
- private:
-  std::mutex initialized_mutex;
-  std::mutex event_mutex;
-  std::mutex sco_mutex;
-  std::mutex acl_mutex;
-  std::condition_variable initialized_condition;
-  std::condition_variable event_condition;
-  std::condition_variable sco_condition;
-  std::condition_variable acl_condition;
-  int initialized_count;
-  int event_count;
-  int sco_count;
-  int acl_count;
 };
 
 // A class for test environment setup (kept since this file is a template).
@@ -334,11 +260,12 @@
   int status_event_count = 0;
   hidl_vec<uint8_t> event;
   do {
-    wait_for_event();
-    EXPECT_LT(static_cast<size_t>(0), event_queue.size());
-    if (event_queue.size() == 0) {
-      event.resize(0);
-      break;
+      EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
+                      .no_timeout);
+      EXPECT_LT(static_cast<size_t>(0), event_queue.size());
+      if (event_queue.size() == 0) {
+          event.resize(0);
+          break;
     }
     event = event_queue.front();
     event_queue.pop();
@@ -366,7 +293,8 @@
   hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_BUFFER_SIZE;
   bluetooth->sendHciCommand(cmd);
 
-  wait_for_event();
+  EXPECT_TRUE(
+      bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout);
 
   EXPECT_LT(static_cast<size_t>(0), event_queue.size());
   if (event_queue.size() == 0) return;
@@ -420,7 +348,8 @@
     bluetooth->sendHciCommand(cmd);
 
     // Check the loopback of the HCI packet
-    wait_for_event();
+    EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
+                    .no_timeout);
     hidl_vec<uint8_t> event = event_queue.front();
     event_queue.pop();
     size_t compare_length =
@@ -456,7 +385,8 @@
     bluetooth->sendScoData(sco_vector);
 
     // Check the loopback of the SCO packet
-    wait_for_sco();
+    EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameScoEventReceived)
+                    .no_timeout);
     hidl_vec<uint8_t> sco_loopback = sco_queue.front();
     sco_queue.pop();
 
@@ -501,7 +431,8 @@
     bluetooth->sendAclData(acl_vector);
 
     // Check the loopback of the ACL packet
-    wait_for_acl();
+    EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameAclEventReceived)
+                    .no_timeout);
     hidl_vec<uint8_t> acl_loopback = acl_queue.front();
     acl_queue.pop();
 
@@ -527,19 +458,20 @@
 
 // Return the number of completed packets reported by the controller.
 int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
-  wait_for_event();
-  int packets_processed = 0;
-  while (event_queue.size() > 0) {
-    hidl_vec<uint8_t> event = event_queue.front();
-    event_queue.pop();
+    EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
+                    .no_timeout);
+    int packets_processed = 0;
+    while (event_queue.size() > 0) {
+        hidl_vec<uint8_t> event = event_queue.front();
+        event_queue.pop();
 
-    EXPECT_EQ(EVENT_NUMBER_OF_COMPLETED_PACKETS, event[EVENT_CODE_BYTE]);
-    EXPECT_EQ(1, event[EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES]);
+        EXPECT_EQ(EVENT_NUMBER_OF_COMPLETED_PACKETS, event[EVENT_CODE_BYTE]);
+        EXPECT_EQ(1, event[EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES]);
 
-    uint16_t event_handle = event[3] + (event[4] << 8);
-    EXPECT_EQ(handle, event_handle);
+        uint16_t event_handle = event[3] + (event[4] << 8);
+        EXPECT_EQ(handle, event_handle);
 
-    packets_processed += event[5] + (event[6] << 8);
+        packets_processed += event[5] + (event[6] << 8);
   }
   return packets_processed;
 }
@@ -554,32 +486,34 @@
   int connection_event_count = 0;
   hidl_vec<uint8_t> event;
   do {
-    wait_for_event();
-    event = event_queue.front();
-    event_queue.pop();
-    EXPECT_GT(event.size(),
-              static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
-    if (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE) {
+      EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
+                      .no_timeout);
+      event = event_queue.front();
+      event_queue.pop();
       EXPECT_GT(event.size(),
-                static_cast<size_t>(EVENT_CONNECTION_COMPLETE_TYPE));
-      EXPECT_EQ(event[EVENT_LENGTH_BYTE],
-                EVENT_CONNECTION_COMPLETE_PARAM_LENGTH);
-      uint8_t connection_type = event[EVENT_CONNECTION_COMPLETE_TYPE];
+                static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+      if (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE) {
+          EXPECT_GT(event.size(),
+                    static_cast<size_t>(EVENT_CONNECTION_COMPLETE_TYPE));
+          EXPECT_EQ(event[EVENT_LENGTH_BYTE],
+                    EVENT_CONNECTION_COMPLETE_PARAM_LENGTH);
+          uint8_t connection_type = event[EVENT_CONNECTION_COMPLETE_TYPE];
 
-      EXPECT_TRUE(connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO ||
-                  connection_type == EVENT_CONNECTION_COMPLETE_TYPE_ACL);
+          EXPECT_TRUE(connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO ||
+                      connection_type == EVENT_CONNECTION_COMPLETE_TYPE_ACL);
 
-      // Save handles
-      uint16_t handle = event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE] |
-                        event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE + 1] << 8;
-      if (connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO)
-        sco_handles.push_back(handle);
-      else
-        acl_handles.push_back(handle);
+          // Save handles
+          uint16_t handle = event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE] |
+                            event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE + 1]
+                                << 8;
+          if (connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO)
+              sco_handles.push_back(handle);
+          else
+              acl_handles.push_back(handle);
 
-      ALOGD("Connect complete type = %d handle = %d",
-            event[EVENT_CONNECTION_COMPLETE_TYPE], handle);
-      connection_event_count++;
+          ALOGD("Connect complete type = %d handle = %d",
+                event[EVENT_CONNECTION_COMPLETE_TYPE], handle);
+          connection_event_count++;
     }
   } while (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE);
 
@@ -592,7 +526,7 @@
 }
 
 // Empty test: Initialize()/Close() are called in SetUp()/TearDown().
-TEST_F(BluetoothHidlTest, InitializeAndClose) { }
+TEST_F(BluetoothHidlTest, InitializeAndClose) {}
 
 // Send an HCI Reset with sendHciCommand and wait for a command complete event.
 TEST_F(BluetoothHidlTest, HciReset) {
@@ -607,7 +541,8 @@
   hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION;
   bluetooth->sendHciCommand(cmd);
 
-  wait_for_event();
+  EXPECT_TRUE(
+      bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout);
 
   hidl_vec<uint8_t> event = event_queue.front();
   event_queue.pop();
@@ -627,7 +562,8 @@
   hidl_vec<uint8_t> cmd = COMMAND_HCI_SHOULD_BE_UNKNOWN;
   bluetooth->sendHciCommand(cmd);
 
-  wait_for_event();
+  EXPECT_TRUE(
+      bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout);
 
   hidl_vec<uint8_t> event = event_queue.front();
   event_queue.pop();
diff --git a/camera/device/1.0/ICameraDevice.hal b/camera/device/1.0/ICameraDevice.hal
index 52d6cf0..d4aa8cc 100644
--- a/camera/device/1.0/ICameraDevice.hal
+++ b/camera/device/1.0/ICameraDevice.hal
@@ -328,6 +328,20 @@
     releaseRecordingFrameHandle(MemoryId memId, uint32_t bufferIndex, handle frame);
 
     /**
+     * Release a batch of record frames previously returned by CAMERA_MSG_VIDEO_FRAME
+     * in handleCallbackTimestampBatch.
+     *
+     * It is camera HAL client's responsibility to release video recording
+     * frames sent out by the camera HAL before the camera HAL receives a call
+     * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to
+     * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's
+     * responsibility to manage the life-cycle of the video recording frames.
+     *
+     * @param batch A batch of recording frames to be released by camera HAL.
+     */
+    releaseRecordingFrameHandleBatch(vec<VideoFrameMessage> batch);
+
+    /**
      * Start auto focus.
      *
      * The notification callback routine is called with
diff --git a/camera/device/1.0/ICameraDeviceCallback.hal b/camera/device/1.0/ICameraDeviceCallback.hal
index 1b0db24..1dfcd80 100644
--- a/camera/device/1.0/ICameraDeviceCallback.hal
+++ b/camera/device/1.0/ICameraDeviceCallback.hal
@@ -92,10 +92,24 @@
      * @param timestamp The time this buffer was captured by the camera, in
      *     nanoseconds.
      *
-     * @return frameId a frame ID to be used with releaseRecordingFrameId later
-     *
      */
     handleCallbackTimestamp(DataCallbackMsg msgType, handle frameData, MemoryId data,
             uint32_t bufferIndex, int64_t timestamp);
 
+    /**
+     * Send a batch of image data buffer to the camera service, with timestamps
+     *
+     * This callback can be used to send multiple frames to camera framework in one callback, which
+     * reduce number of callbacks in performance intensive use cases, such as high speed video
+     * recording. The HAL must not mix use of this method with handleCallbackTimestamp in one
+     * recording session (between startRecording and stopRecording)
+     *
+     * @param msgType The kind of image buffer data this call represents.
+     * @param batch a vector messages. Each message contains a image buffer and a timestamp. The
+     *     messages must be ordered in time from lower index to higher index, so that timestamp of
+     *     i-th message is always smaller than i+1-th message.
+     *
+     */
+    handleCallbackTimestampBatch(DataCallbackMsg msgType, vec<HandleTimestampMessage> batch);
+
 };
diff --git a/camera/device/1.0/ICameraDevicePreviewCallback.hal b/camera/device/1.0/ICameraDevicePreviewCallback.hal
index 4c9b517..e772301 100644
--- a/camera/device/1.0/ICameraDevicePreviewCallback.hal
+++ b/camera/device/1.0/ICameraDevicePreviewCallback.hal
@@ -17,7 +17,6 @@
 package android.hardware.camera.device@1.0;
 
 import android.hardware.camera.common@1.0::types;
-import android.hardware.graphics.allocator@2.0::types;
 import android.hardware.graphics.common@1.0::types;
 
 /**
@@ -89,7 +88,7 @@
      *
      * @return Status The status code for this operation.
      */
-    setUsage(ProducerUsage usage) generates (Status status);
+    setUsage(ProducerUsageFlags usage) generates (Status status);
 
     /**
      * Set the expected buffering mode for the preview output.
diff --git a/camera/device/1.0/default/Android.bp b/camera/device/1.0/default/Android.bp
index 5688fc1..a2fd0b0 100644
--- a/camera/device/1.0/default/Android.bp
+++ b/camera/device/1.0/default/Android.bp
@@ -22,8 +22,8 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.camera.common@1.0-helper"
+        "android.hardware.camera.common@1.0-helper",
+        "libgrallocusage"
     ],
     export_include_dirs: ["."]
 }
-
diff --git a/camera/device/1.0/default/CameraDevice.cpp b/camera/device/1.0/default/CameraDevice.cpp
index 819525b..5e3fcf2 100644
--- a/camera/device/1.0/default/CameraDevice.cpp
+++ b/camera/device/1.0/default/CameraDevice.cpp
@@ -20,6 +20,8 @@
 #include <hardware/gralloc1.h>
 #include <utils/Trace.h>
 
+#include <grallocusage/GrallocUsageConversion.h>
+
 #include "CameraDevice_1_0.h"
 
 namespace android {
@@ -29,7 +31,6 @@
 namespace V1_0 {
 namespace implementation {
 
-using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
 
 HandleImporter& CameraDevice::sHandleImporter = HandleImporter::getInstance();
@@ -252,7 +253,10 @@
     }
 
     object->cleanUpCirculatingBuffers();
-    return getStatusT(object->mPreviewCallback->setUsage((ProducerUsage) usage));
+    ProducerUsageFlags producerUsage;
+    uint64_t consumerUsage;
+    ::android_convertGralloc0To1Usage(usage, &producerUsage, &consumerUsage);
+    return getStatusT(object->mPreviewCallback->setUsage(producerUsage));
 }
 
 int CameraDevice::sSetSwapInterval(struct preview_stream_ops *w, int interval) {
@@ -420,6 +424,39 @@
     }
 }
 
+void CameraDevice::handleCallbackTimestamp(
+        nsecs_t timestamp, int32_t msg_type,
+        MemoryId memId , unsigned index, native_handle_t* handle) {
+    uint32_t batchSize = 0;
+    {
+        Mutex::Autolock _l(mBatchLock);
+        batchSize = mBatchSize;
+    }
+
+    if (batchSize == 0) { // non-batch mode
+        mDeviceCallback->handleCallbackTimestamp(
+                (DataCallbackMsg) msg_type, handle, memId, index, timestamp);
+    } else { // batch mode
+        Mutex::Autolock _l(mBatchLock);
+        size_t inflightSize = mInflightBatch.size();
+        if (inflightSize == 0) {
+            mBatchMsgType = msg_type;
+        } else if (mBatchMsgType != msg_type) {
+            ALOGE("%s: msg_type change (from %d to %d) is not supported!",
+                    __FUNCTION__, mBatchMsgType, msg_type);
+            return;
+        }
+        mInflightBatch.push_back({handle, memId, index, timestamp});
+
+        // Send batched frames to camera framework
+        if (mInflightBatch.size() >= batchSize) {
+            mDeviceCallback->handleCallbackTimestampBatch(
+                    (DataCallbackMsg) mBatchMsgType, mInflightBatch);
+            mInflightBatch.clear();
+        }
+    }
+}
+
 void CameraDevice::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
         const camera_memory_t *data, unsigned index, void *user) {
     ALOGV("%s", __FUNCTION__);
@@ -450,8 +487,7 @@
             object->mDeviceCallback->dataCallbackTimestamp(
                     (DataCallbackMsg) msg_type, mem->handle.mId, index, timestamp);
         } else {
-            object->mDeviceCallback->handleCallbackTimestamp(
-                    (DataCallbackMsg) msg_type, handle, mem->handle.mId, index, timestamp);
+            object->handleCallbackTimestamp(timestamp, msg_type, mem->handle.mId, index, handle);
         }
     }
 }
@@ -827,6 +863,17 @@
     return Void();
 }
 
+Return<void> CameraDevice::releaseRecordingFrameHandleBatch(
+        const hidl_vec<VideoFrameMessage>& msgs) {
+    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
+    Mutex::Autolock _l(mLock);
+    for (auto& msg : msgs) {
+        releaseRecordingFrameLocked(
+                msg.data, msg.bufferIndex, msg.frameData.getNativeHandle());
+    }
+    return Void();
+}
+
 Return<Status> CameraDevice::autoFocus() {
     ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
     Mutex::Autolock _l(mLock);
diff --git a/camera/device/1.0/default/CameraDevice_1_0.h b/camera/device/1.0/default/CameraDevice_1_0.h
index 2568f86..ad5f582 100644
--- a/camera/device/1.0/default/CameraDevice_1_0.h
+++ b/camera/device/1.0/default/CameraDevice_1_0.h
@@ -93,6 +93,8 @@
     Return<void> releaseRecordingFrame(uint32_t memId, uint32_t bufferIndex) override;
     Return<void> releaseRecordingFrameHandle(
             uint32_t memId, uint32_t bufferIndex, const hidl_handle& frame) override;
+    Return<void> releaseRecordingFrameHandleBatch(
+            const hidl_vec<VideoFrameMessage>&) override;
     Return<Status> autoFocus() override;
     Return<Status> cancelAutoFocus() override;
     Return<Status> takePicture() override;
@@ -169,6 +171,16 @@
 
     bool mMetadataMode = false;
 
+    mutable Mutex mBatchLock;
+    // Start of protection scope for mBatchLock
+    uint32_t mBatchSize = 0; // 0 for non-batch mode, set to other value to start batching
+    int32_t mBatchMsgType;   // Maybe only allow DataCallbackMsg::VIDEO_FRAME?
+    std::vector<HandleTimestampMessage> mInflightBatch;
+    // End of protection scope for mBatchLock
+
+    void handleCallbackTimestamp(
+            nsecs_t timestamp, int32_t msg_type,
+            MemoryId memId , unsigned index, native_handle_t* handle);
     void releaseRecordingFrameLocked(uint32_t memId, uint32_t bufferIndex, const native_handle_t*);
 
     // shared memory methods
@@ -178,13 +190,13 @@
     // Device callback forwarding methods
     static void sNotifyCb(int32_t msg_type, int32_t ext1, int32_t ext2, void *user);
     static void sDataCb(int32_t msg_type, const camera_memory_t *data, unsigned int index,
-                          camera_frame_metadata_t *metadata, void *user);
+                        camera_frame_metadata_t *metadata, void *user);
     static void sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
                                     const camera_memory_t *data, unsigned index, void *user);
 
     // Preview window callback forwarding methods
     static int sDequeueBuffer(struct preview_stream_ops* w,
-                                buffer_handle_t** buffer, int *stride);
+                              buffer_handle_t** buffer, int *stride);
 
     static int sLockBuffer(struct preview_stream_ops* w, buffer_handle_t* buffer);
 
@@ -195,7 +207,7 @@
     static int sSetBufferCount(struct preview_stream_ops* w, int count);
 
     static int sSetBuffersGeometry(struct preview_stream_ops* w,
-                                     int width, int height, int format);
+                                   int width, int height, int format);
 
     static int sSetCrop(struct preview_stream_ops *w, int left, int top, int right, int bottom);
 
diff --git a/camera/device/1.0/types.hal b/camera/device/1.0/types.hal
index bf632d1..0b3445f 100644
--- a/camera/device/1.0/types.hal
+++ b/camera/device/1.0/types.hal
@@ -16,6 +16,10 @@
 
 package android.hardware.camera.device@1.0;
 
+import android.hardware.graphics.allocator@2.0::types;
+
+typedef bitfield<ProducerUsage> ProducerUsageFlags;
+
 enum CameraFacing : uint32_t {
     /** The facing of the camera is opposite to that of the screen. */
     BACK = 0,
@@ -254,3 +258,36 @@
  * between the HAL and the framework.
  */
 typedef uint32_t MemoryId;
+
+/*
+ * Struct containing arguments of ICameraDeviceCallback::handleCallbackTimestamp.
+ * Used to send a batch of messages in ICameraDeviceCallback::handleCallbackTimestampBatch.
+ */
+struct HandleTimestampMessage {
+    // The handle of image buffer data.
+    handle frameData;
+
+    // A memory handle to the buffer containing the data
+    MemoryId data;
+
+    // The offset into the memory handle where the buffer starts.
+    uint32_t bufferIndex;
+
+    // The time this buffer was captured by the camera, in nanoseconds
+    int64_t timestamp;
+};
+
+/*
+ * Struct containing arguments of ICameraDevice::releaseRecordingFrameHandle.
+ * Used by camera framework to send a batch of recording frames back to camera HAL.
+ */
+struct VideoFrameMessage {
+    // The handle of image buffer data.
+    handle frameData;
+
+    // A memory handle to the buffer containing the data
+    MemoryId data;
+
+    // The offset into the memory handle where the buffer starts.
+    uint32_t bufferIndex;
+};
diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp
index e0dc5ff..5a81d41 100644
--- a/camera/device/3.2/default/Android.bp
+++ b/camera/device/3.2/default/Android.bp
@@ -17,7 +17,8 @@
         "libcamera_metadata"
     ],
     static_libs: [
-        "android.hardware.camera.common@1.0-helper"
+        "android.hardware.camera.common@1.0-helper",
+        "libgrallocusage"
     ],
     export_include_dirs: ["."]
 }
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 5b3024b..f2f9e5e 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -611,7 +611,7 @@
                 return Void();
             }
             mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation;
-            mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage;
+            mStreamMap[id].usage = convertFromHidlUsage(requestedConfiguration.streams[i].usage);
         }
         streams[i] = &mStreamMap[id];
     }
diff --git a/camera/device/3.2/default/convert.cpp b/camera/device/3.2/default/convert.cpp
index 35676df..c99d903 100644
--- a/camera/device/3.2/default/convert.cpp
+++ b/camera/device/3.2/default/convert.cpp
@@ -15,8 +15,12 @@
  */
 
 #define LOG_TAG "android.hardware.camera.device@3.2-convert-impl"
+#include <inttypes.h>
+
 #include <android/log.h>
 
+#include <grallocusage/GrallocUsageConversion.h>
+
 #include "include/convert.h"
 
 namespace android {
@@ -28,6 +32,7 @@
 
 using ::android::hardware::graphics::common::V1_0::Dataspace;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::hardware::graphics::allocator::V2_0::ConsumerUsage;
 using ::android::hardware::camera::device::V3_2::ConsumerUsageFlags;
 using ::android::hardware::camera::device::V3_2::ProducerUsageFlags;
 
@@ -66,23 +71,37 @@
     dst->format = (int) src.format;
     dst->data_space = (android_dataspace_t) src.dataSpace;
     dst->rotation = (int) src.rotation;
-    dst->usage = (uint32_t) src.usage;
+    dst->usage = convertFromHidlUsage(src.usage);
     // Fields to be filled by HAL (max_buffers, priv) are initialized to 0
     dst->max_buffers = 0;
     dst->priv = 0;
     return;
 }
 
+uint32_t convertFromHidlUsage(ConsumerUsageFlags usage) {
+    uint32_t dstUsage = 0;
+    dstUsage = ::android_convertGralloc1To0Usage(/*producerUsage*/ 0, usage);
+    // Compatibility workaround - add HW_CAMERA_ZSL when ConsumerUsage.CAMERA is set, to
+    // match pre-HIDL expected usage flags
+    if ( (usage & ConsumerUsage::CAMERA) == static_cast<uint64_t>(ConsumerUsage::CAMERA)) {
+        dstUsage |= GRALLOC_USAGE_HW_CAMERA_ZSL;
+    }
+    return dstUsage;
+}
+
 void convertToHidl(const Camera3Stream* src, HalStream* dst) {
     dst->id = src->mId;
     dst->overrideFormat = (PixelFormat) src->format;
     dst->maxBuffers = src->max_buffers;
+    ConsumerUsageFlags consumerUsage;
+    ProducerUsageFlags producerUsage;
+    ::android_convertGralloc0To1Usage(src->usage, &producerUsage, &consumerUsage);
     if (src->stream_type == CAMERA3_STREAM_OUTPUT) {
         dst->consumerUsage = (ConsumerUsageFlags) 0;
-        dst->producerUsage = (ProducerUsageFlags) src->usage;
+        dst->producerUsage = producerUsage;
     } else if (src->stream_type == CAMERA3_STREAM_INPUT) {
         dst->producerUsage = (ProducerUsageFlags) 0;
-        dst->consumerUsage = (ConsumerUsageFlags) src->usage;
+        dst->consumerUsage = consumerUsage;
     } else {
         //Should not reach here per current HIDL spec, but we might end up adding
         // bi-directional stream to HIDL.
diff --git a/camera/device/3.2/default/include/convert.h b/camera/device/3.2/default/include/convert.h
index 96891f0..7c8e02f 100644
--- a/camera/device/3.2/default/include/convert.h
+++ b/camera/device/3.2/default/include/convert.h
@@ -45,6 +45,8 @@
 void convertFromHidl(const Stream &src, Camera3Stream* dst);
 void convertToHidl(const Camera3Stream* src, HalStream* dst);
 
+uint32_t convertFromHidlUsage(ConsumerUsageFlags usage);
+
 void convertFromHidl(
         buffer_handle_t*, BufferStatus, camera3_stream_t*, int acquireFence, // inputs
         camera3_stream_buffer_t* dst);
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index a0be5cb..02c42c9 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -33,7 +33,10 @@
         "libgui",
         "libui"
     ],
-    static_libs: ["VtsHalHidlTargetTestBase"],
+    static_libs: [
+        "VtsHalHidlTargetTestBase",
+        "libgrallocusage"
+    ],
     cflags: [
         "-O0",
         "-g",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 47cc9f1..4d3c6eb 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -21,6 +21,7 @@
 #include "CameraParameters.h"
 #include <system/camera.h>
 #include <android/log.h>
+#include <grallocusage/GrallocUsageConversion.h>
 #include <ui/GraphicBuffer.h>
 #include <VtsHalHidlTargetTestBase.h>
 #include <gui/BufferQueue.h>
@@ -53,6 +54,7 @@
 using ::android::Surface;
 using ::android::CameraParameters;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::hardware::graphics::allocator::V2_0::ConsumerUsage;
 using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
 using ::android::hardware::camera::common::V1_0::Status;
 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
@@ -60,6 +62,8 @@
 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
+using ::android::hardware::camera::device::V3_2::ProducerUsageFlags;
+using ::android::hardware::camera::device::V3_2::ConsumerUsageFlags;
 using ::android::hardware::camera::device::V3_2::ICameraDevice;
 using ::android::hardware::camera::device::V3_2::BufferCache;
 using ::android::hardware::camera::device::V3_2::CaptureRequest;
@@ -80,6 +84,7 @@
 using ::android::hardware::camera::device::V3_2::MsgType;
 using ::android::hardware::camera::device::V3_2::ErrorMsg;
 using ::android::hardware::camera::device::V3_2::ErrorCode;
+using ::android::hardware::camera::device::V1_0::ProducerUsageFlags;
 using ::android::hardware::camera::device::V1_0::CameraFacing;
 using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg;
 using ::android::hardware::camera::device::V1_0::CommandType;
@@ -87,6 +92,7 @@
 using ::android::hardware::camera::device::V1_0::CameraFrameMetadata;
 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
 using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
+using ::android::hardware::camera::device::V1_0::HandleTimestampMessage;
 
 const char kCameraPassthroughServiceName[] = "legacy/0";
 const uint32_t kMaxPreviewWidth = 1920;
@@ -232,7 +238,7 @@
     Return<Status> setCrop(int32_t left, int32_t top,
             int32_t right, int32_t bottom) override;
 
-    Return<Status> setUsage(ProducerUsage usage) override;
+    Return<Status> setUsage(ProducerUsageFlags usage) override;
 
     Return<Status> setSwapInterval(int32_t interval) override;
 
@@ -407,10 +413,11 @@
     return mapToStatus(rc);
 }
 
-Return<Status> PreviewWindowCb::setUsage(ProducerUsage usage) {
-    auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
+Return<Status> PreviewWindowCb::setUsage(ProducerUsageFlags usage) {
+    int dstUsage = ::android_convertGralloc1To0Usage(usage, /*consumerUsage*/ 0);
+    auto rc = native_window_set_usage(mAnw.get(), dstUsage);
     if (rc == ::android::OK) {
-        mPreviewUsage =  static_cast<int>(usage);
+        mPreviewUsage = dstUsage;
     }
     return mapToStatus(rc);
 }
@@ -511,6 +518,10 @@
                 const hidl_handle& frameData,uint32_t data,
                 uint32_t bufferIndex, int64_t timestamp) override;
 
+        Return<void> handleCallbackTimestampBatch(DataCallbackMsg msgType,
+                const ::android::hardware::hidl_vec<HandleTimestampMessage>& batch) override;
+
+
      private:
         CameraHidlTest *mParent;               // Parent object
     };
@@ -667,6 +678,23 @@
     return Void();
 }
 
+Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestampBatch(
+        DataCallbackMsg msgType,
+        const hidl_vec<HandleTimestampMessage>& batch) {
+    std::unique_lock<std::mutex> l(mParent->mLock);
+    for (auto& msg : batch) {
+        mParent->mDataMessageTypeReceived = msgType;
+        mParent->mVideoBufferIndex = msg.bufferIndex;
+        if (mParent->mMemoryPool.count(msg.data) == 0) {
+            ADD_FAILURE() << "memory pool ID " << msg.data << " not found";
+        }
+        mParent->mVideoData = msg.data;
+        mParent->mVideoNativeHandle = msg.frameData;
+        mParent->mResultCondition.notify_one();
+    }
+    return Void();
+}
+
 Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
         const hidl_vec<CaptureResult>& results) {
     if (nullptr == mParent) {
@@ -2177,7 +2205,7 @@
                             static_cast<uint32_t> (input.width),
                             static_cast<uint32_t> (input.height),
                             static_cast<PixelFormat> (input.format),
-                            GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
+                            static_cast<ConsumerUsageFlags>(ConsumerUsage::CAMERA), 0,
                             StreamRotation::ROTATION_0};
                     Stream inputStream = {streamId++, StreamType::INPUT,
                             static_cast<uint32_t> (input.width),
@@ -2409,7 +2437,7 @@
                             static_cast<uint32_t> (blobIter.width),
                             static_cast<uint32_t> (blobIter.height),
                             static_cast<PixelFormat> (blobIter.format),
-                            GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
+                            static_cast<ConsumerUsageFlags>(ConsumerUsage::VIDEO_ENCODER), 0,
                             StreamRotation::ROTATION_0};
                     ::android::hardware::hidl_vec<Stream> streams = {
                             videoStream, blobStream};
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
index 8741bdd..563d854 100644
--- a/configstore/1.0/default/android.hardware.configstore@1.0-service.rc
+++ b/configstore/1.0/default/android.hardware.configstore@1.0-service.rc
@@ -1,4 +1,4 @@
 service configstore-hal-1-0 /vendor/bin/hw/android.hardware.configstore@1.0-service
-    class hal
+    class hal animation
     user system
     group system
diff --git a/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc b/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc
index 3e2edda..9a08f66 100644
--- a/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc
+++ b/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc
@@ -1,5 +1,5 @@
 service gralloc-2-0 /vendor/bin/hw/android.hardware.graphics.allocator@2.0-service
-    class hal
+    class hal animation
     user system
     group graphics drmrpc
     onrestart restart surfaceflinger
diff --git a/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc b/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc
index b6060db..51b0e3b 100644
--- a/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc
+++ b/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc
@@ -1,5 +1,5 @@
 service hwcomposer-2-1 /vendor/bin/hw/android.hardware.graphics.composer@2.1-service
-    class hal
+    class hal animation
     user system
     group graphics drmrpc
     capabilities SYS_NICE
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index aa3bc9c..9da58e2 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -22,10 +22,8 @@
 #include <android/hardware/nfc/1.0/types.h>
 #include <hardware/nfc.h>
 
+#include <VtsHalHidlTargetCallbackBase.h>
 #include <VtsHalHidlTargetTestBase.h>
-#include <chrono>
-#include <condition_variable>
-#include <mutex>
 
 using ::android::hardware::nfc::V1_0::INfc;
 using ::android::hardware::nfc::V1_0::INfcClientCallback;
@@ -55,6 +53,43 @@
 #define VERSION 0x11
 #define TIMEOUT_PERIOD 5
 
+constexpr char kCallbackNameSendEvent[] = "sendEvent";
+constexpr char kCallbackNameSendData[] = "sendData";
+
+class NfcClientCallbackArgs {
+   public:
+    NfcEvent last_event_;
+    NfcStatus last_status_;
+    NfcData last_data_;
+};
+
+/* Callback class for data & Event. */
+class NfcClientCallback
+    : public ::testing::VtsHalHidlTargetCallbackBase<NfcClientCallbackArgs>,
+      public INfcClientCallback {
+   public:
+    virtual ~NfcClientCallback() = default;
+
+    /* sendEvent callback function - Records the Event & Status
+     * and notifies the TEST
+     **/
+    Return<void> sendEvent(NfcEvent event, NfcStatus event_status) override {
+        NfcClientCallbackArgs args;
+        args.last_event_ = event;
+        args.last_status_ = event_status;
+        NotifyFromCallback(kCallbackNameSendEvent, args);
+        return Void();
+    };
+
+    /* sendData callback function. Records the data and notifies the TEST*/
+    Return<void> sendData(const NfcData& data) override {
+        NfcClientCallbackArgs args;
+        args.last_data_ = data;
+        NotifyFromCallback(kCallbackNameSendData, args);
+        return Void();
+    };
+};
+
 // The main test class for NFC HIDL HAL.
 class NfcHidlTest : public ::testing::VtsHalHidlTargetTestBase {
  public:
@@ -62,88 +97,28 @@
     nfc_ = ::testing::VtsHalHidlTargetTestBase::getService<INfc>();
     ASSERT_NE(nfc_, nullptr);
 
-    nfc_cb_ = new NfcClientCallback(*this);
+    nfc_cb_ = new NfcClientCallback();
     ASSERT_NE(nfc_cb_, nullptr);
 
-    count = 0;
-    last_event_ = NfcEvent::ERROR;
-    last_status_ = NfcStatus::FAILED;
-
     EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
     // Wait for OPEN_CPLT event
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(NfcEvent::OPEN_CPLT, last_event_);
-    EXPECT_EQ(NfcStatus::OK, last_status_);
+    auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+    EXPECT_TRUE(res.no_timeout);
+    EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
+    EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
   }
 
   virtual void TearDown() override {
     EXPECT_EQ(NfcStatus::OK, nfc_->close());
     // Wait for CLOSE_CPLT event
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(NfcEvent::CLOSE_CPLT, last_event_);
-    EXPECT_EQ(NfcStatus::OK, last_status_);
+    auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+    EXPECT_TRUE(res.no_timeout);
+    EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
+    EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
   }
 
-  /* Used as a mechanism to inform the test about data/event callback */
-  inline void notify() {
-    std::unique_lock<std::mutex> lock(mtx);
-    count++;
-    cv.notify_one();
-  }
-
-  /* Test code calls this function to wait for data/event callback */
-  inline std::cv_status wait() {
-    std::unique_lock<std::mutex> lock(mtx);
-
-    std::cv_status status = std::cv_status::no_timeout;
-    auto now = std::chrono::system_clock::now();
-    while (count == 0) {
-      status = cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
-      if (status == std::cv_status::timeout) return status;
-    }
-    count--;
-    return status;
-  }
-
-  /* Callback class for data & Event. */
-  class NfcClientCallback : public INfcClientCallback {
-    NfcHidlTest& parent_;
-
-   public:
-    NfcClientCallback(NfcHidlTest& parent) : parent_(parent){};
-
-    virtual ~NfcClientCallback() = default;
-
-    /* sendEvent callback function - Records the Event & Status
-     * and notifies the TEST
-     **/
-    Return<void> sendEvent(NfcEvent event, NfcStatus event_status) override {
-      parent_.last_event_ = event;
-      parent_.last_status_ = event_status;
-      parent_.notify();
-      return Void();
-    };
-
-    /* sendData callback function. Records the data and notifies the TEST*/
-    Return<void> sendData(const NfcData& data) override {
-      size_t size = parent_.last_data_.size();
-      parent_.last_data_.resize(size + 1);
-      parent_.last_data_[size] = data;
-      parent_.notify();
-      return Void();
-    };
-  };
-
   sp<INfc> nfc_;
-  sp<INfcClientCallback> nfc_cb_;
-  NfcEvent last_event_;
-  NfcStatus last_status_;
-  hidl_vec<NfcData> last_data_;
-
- private:
-  std::mutex mtx;
-  std::condition_variable cv;
-  int count;
+  sp<NfcClientCallback> nfc_cb_;
 };
 
 // A class for test environment setup (kept since this file is a template).
@@ -175,12 +150,12 @@
   NfcData data = cmd;
   EXPECT_EQ(data.size(), nfc_->write(data));
   // Wait for CORE_RESET_RSP
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(1ul, last_data_.size());
-  EXPECT_EQ(6ul, last_data_[0].size());
-  EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
-  EXPECT_GE(VERSION, last_data_[0][4]);
-  EXPECT_EQ(0ul, last_data_[0][5]);
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(6ul, res.args->last_data_.size());
+  EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
+  EXPECT_GE(VERSION, res.args->last_data_[4]);
+  EXPECT_EQ(0ul, res.args->last_data_[5]);
 }
 
 /*
@@ -194,12 +169,12 @@
   NfcData data = cmd;
   EXPECT_EQ(data.size(), nfc_->write(data));
   // Wait for CORE_RESET_RSP
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(1ul, last_data_.size());
-  EXPECT_EQ(6ul, last_data_[0].size());
-  EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
-  EXPECT_GE(VERSION, last_data_[0][4]);
-  EXPECT_EQ(1ul, last_data_[0][5]);
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(6ul, res.args->last_data_.size());
+  EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
+  EXPECT_GE(VERSION, res.args->last_data_[4]);
+  EXPECT_EQ(1ul, res.args->last_data_[5]);
 }
 
 /*
@@ -214,10 +189,10 @@
   NfcData data = cmd;
   EXPECT_EQ(data.size(), nfc_->write(data));
   // Wait for RSP
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(1ul, last_data_.size());
-  EXPECT_EQ(4ul, last_data_[0].size());
-  EXPECT_EQ(SYNTAX_ERROR, last_data_[0][3]);
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(4ul, res.args->last_data_.size());
+  EXPECT_EQ(SYNTAX_ERROR, res.args->last_data_[3]);
 }
 
 /*
@@ -236,29 +211,27 @@
   size_t size = data.size();
 
   for (int i = 0; i < 100; i++) {
-    last_data_.resize(0);
     data.resize(++size);
     data[size - 1] = 0xFF;
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_INTERFACE_ERROR_NTF
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(1ul, last_data_.size());
-    EXPECT_EQ(5ul, last_data_[0].size());
-    EXPECT_EQ(0x60, last_data_[0][0]);
-    EXPECT_EQ(0x08, last_data_[0][1]);
-    EXPECT_EQ(0x02, last_data_[0][2]);
-    EXPECT_EQ(SYNTAX_ERROR, last_data_[0][3]);
+    auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+    EXPECT_TRUE(res.no_timeout);
+    EXPECT_EQ(5ul, res.args->last_data_.size());
+    EXPECT_EQ(0x60, res.args->last_data_[0]);
+    EXPECT_EQ(0x08, res.args->last_data_[1]);
+    EXPECT_EQ(0x02, res.args->last_data_[2]);
+    EXPECT_EQ(SYNTAX_ERROR, res.args->last_data_[3]);
   }
 
   cmd = CORE_CONN_CREATE_CMD;
   data = cmd;
-  last_data_.resize(0);
   EXPECT_EQ(data.size(), nfc_->write(data));
   // Wait for CORE_CONN_CREATE_RSP
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(1ul, last_data_.size());
-  EXPECT_EQ(7ul, last_data_[0].size());
-  EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(7ul, res.args->last_data_.size());
+  EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
 }
 /*
  * Bandwidth:
@@ -273,40 +246,48 @@
   NfcData data = cmd;
   EXPECT_EQ(data.size(), nfc_->write(data));
   // Wait for CORE_CONN_CREATE_RSP
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(1ul, last_data_.size());
-  EXPECT_EQ(7ul, last_data_[0].size());
-  EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
-  uint8_t conn_id = last_data_[0][6];
-  uint32_t max_payload_size = last_data_[0][4];
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(7ul, res.args->last_data_.size());
+  EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
+  uint8_t conn_id = res.args->last_data_[6];
+  uint32_t max_payload_size = res.args->last_data_[4];
 
   for (int loops = 0; loops < NUMBER_LOOPS; loops++) {
-    last_data_.resize(0);
-    data.resize(max_payload_size + LOOP_BACK_HEADER_SIZE);
-    data[0] = conn_id;
-    data[1] = 0x00;
-    data[2] = max_payload_size;
-    for (uint32_t i = 0; i < max_payload_size; i++) {
-      data[i + LOOP_BACK_HEADER_SIZE] = i;
+      res.args->last_data_.resize(0);
+      data.resize(max_payload_size + LOOP_BACK_HEADER_SIZE);
+      data[0] = conn_id;
+      data[1] = 0x00;
+      data[2] = max_payload_size;
+      for (uint32_t i = 0; i < max_payload_size; i++) {
+          data[i + LOOP_BACK_HEADER_SIZE] = i;
     }
     EXPECT_EQ(max_payload_size + LOOP_BACK_HEADER_SIZE, nfc_->write(data));
     // Wait for data and CORE_CONN_CREDITS_NTF
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    // Check if the same data was recieved back
-    EXPECT_EQ(2ul, last_data_.size());
+    auto res1 = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+    EXPECT_TRUE(res1.no_timeout);
+    auto res2 = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+    EXPECT_TRUE(res2.no_timeout);
+    // Check if the same data was received back
+    EXPECT_TRUE(res1.args);
+    EXPECT_TRUE(res2.args);
 
+    NfcData credits_ntf = res1.args->last_data_;
+    NfcData received_data = res2.args->last_data_;
     /* It is possible that CORE_CONN_CREDITS_NTF is received before data,
      * Find the order and do further checks depending on that */
-    uint8_t data_index = last_data_[0].size() == data.size() ? 0 : 1;
-    EXPECT_EQ(data.size(), last_data_[data_index].size());
+    if (received_data.size() != data.size()) {
+        credits_ntf = res2.args->last_data_;
+        received_data = res1.args->last_data_;
+    }
+    EXPECT_EQ(data.size(), received_data.size());
     for (size_t i = 0; i < data.size(); i++) {
-      EXPECT_EQ(data[i], last_data_[data_index][i]);
+        EXPECT_EQ(data[i], received_data[i]);
     }
 
-    EXPECT_EQ(6ul, last_data_[!data_index].size());
+    EXPECT_EQ(6ul, credits_ntf.size());
     // Check if the credit is refilled to 1
-    EXPECT_EQ(1, last_data_[!data_index][5]);
+    EXPECT_EQ(1, credits_ntf[5]);
   }
 }
 
@@ -319,9 +300,10 @@
 TEST_F(NfcHidlTest, PowerCycle) {
   EXPECT_EQ(NfcStatus::OK, nfc_->powerCycle());
   // Wait for NfcEvent.OPEN_CPLT
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(NfcEvent::OPEN_CPLT, last_event_);
-  EXPECT_EQ(NfcStatus::OK, last_status_);
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
 
 /*
@@ -332,17 +314,19 @@
 TEST_F(NfcHidlTest, PowerCycleAfterClose) {
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(NfcEvent::CLOSE_CPLT, last_event_);
-  EXPECT_EQ(NfcStatus::OK, last_status_);
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
   EXPECT_EQ(NfcStatus::FAILED, nfc_->powerCycle());
 
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(NfcEvent::OPEN_CPLT, last_event_);
-  EXPECT_EQ(NfcStatus::OK, last_status_);
+  res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
 
 /*
@@ -353,13 +337,17 @@
 TEST_F(NfcHidlTest, CoreInitialized) {
   NfcData data;
   data.resize(1);
-  for (int i = 0; i <= 6; i++)
-  {
-    data[0] = i;
-    EXPECT_EQ(NfcStatus::OK, nfc_->coreInitialized(data));
-    // Wait for NfcEvent.POST_INIT_CPLT
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(NfcEvent::POST_INIT_CPLT, last_event_);
+  NfcEvent last_event_;
+  for (int i = 0; i <= 6; i++) {
+      data[0] = i;
+      EXPECT_EQ(NfcStatus::OK, nfc_->coreInitialized(data));
+      // Wait for NfcEvent.POST_INIT_CPLT
+      auto res = nfc_cb_->WaitForCallbackAny();
+      if (res.name.compare(kCallbackNameSendEvent) == 0) {
+          last_event_ = res.args->last_event_;
+      }
+      EXPECT_TRUE(res.no_timeout);
+      EXPECT_EQ(NfcEvent::POST_INIT_CPLT, last_event_);
   }
 }
 
@@ -380,17 +368,19 @@
 TEST_F(NfcHidlTest, ControlGrantedAfterClose) {
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(NfcEvent::CLOSE_CPLT, last_event_);
-  EXPECT_EQ(NfcStatus::OK, last_status_);
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
   EXPECT_EQ(NfcStatus::OK, nfc_->controlGranted());
 
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(NfcEvent::OPEN_CPLT, last_event_);
-  EXPECT_EQ(NfcStatus::OK, last_status_);
+  res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
 
 /* PreDiscover:
@@ -409,17 +399,19 @@
 TEST_F(NfcHidlTest, PreDiscoverAfterClose) {
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(NfcEvent::CLOSE_CPLT, last_event_);
-  EXPECT_EQ(NfcStatus::OK, last_status_);
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
   EXPECT_EQ(NfcStatus::OK, nfc_->prediscover());
 
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(NfcEvent::OPEN_CPLT, last_event_);
-  EXPECT_EQ(NfcStatus::OK, last_status_);
+  res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
 
 /*
@@ -430,20 +422,21 @@
 TEST_F(NfcHidlTest, CloseAfterClose) {
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(NfcEvent::CLOSE_CPLT, last_event_);
-  EXPECT_EQ(NfcStatus::OK, last_status_);
+  auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 
   EXPECT_EQ(NfcStatus::FAILED, nfc_->close());
 
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   // Wait for OPEN_CPLT event
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(NfcEvent::OPEN_CPLT, last_event_);
-  EXPECT_EQ(NfcStatus::OK, last_status_);
+  res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
+  EXPECT_TRUE(res.no_timeout);
+  EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
+  EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
 }
 
-
 /*
  * OpenAfterOpen:
  * Calls open() multiple times